I tried to make the weather forecast on the official line by referring to the weather forecast bot of "Dialogue system made with python".

What changed from the content written in the dialogue system made with python

-State transition was made using SQLite3 instead of XML

point

-When I tried to use the code of the book as it is for the official line, I could not retain the transition information, so I used SQLite3.

What to aim for next

Make it possible to cancel the input like "Not Osaka". To the non-task version of the dialogue system made with python

Program structure

Image from Gyazo

Below: Weather forecast official line code (corrected version)

w_system.py


import sys
from PySide2 import QtCore, QtScxml
import requests
import json
from datetime import datetime, timedelta, time
import sqlite3

DATES = ['today','tomorrow']

TYPES = ['weather','temperature']

#Dictionary for getting latitude and longitude from prefecture name
PLACES = {'Hokkaido': (43.06, 141.35), 'Aomori': (40.82, 140.74), 'Iwate': (39.7, 141.15), 'Miyagi': (38.27, 140.87),
        'Akita': (39.72, 140.1), 'Yamagata': (38.24, 140.36), 'Fukushima': (37.75, 140.47), 'Ibaraki': (36.34, 140.45),
        'Tochigi': (36.57, 139.88), 'Gunma': (36.39, 139.06), 'Saitama': (35.86, 139.65), 'Chiba': (35.61, 140.12),
        'Tokyo': (35.69, 139.69), 'Kanagawa': (35.45, 139.64), 'Niigata': (37.9, 139.02), 'Toyama': (36.7, 137.21),
        'Ishikawa': (36.59, 136.63), 'Fukui': (36.07, 136.22), 'Yamanashi': (35.66, 138.57), 'Nagano': (36.65, 138.18),
        'Gifu': (35.39, 136.72), 'Shizuoka': (34.98, 138.38), 'Aichi': (35.18, 136.91), 'Triple': (34.73, 136.51),
        'Shiga': (35.0, 135.87), 'Kyoto': (35.02, 135.76), 'Osaka': (34.69, 135.52), 'Hyogo': (34.69, 135.18),
        'Nara': (34.69, 135.83), 'Wakayama': (34.23, 135.17), 'Tottori': (35.5, 134.24), 'Shimane': (35.47, 133.05),
        'Okayama': (34.66, 133.93), 'Hiroshima': (34.4, 132.46), 'Yamaguchi': (34.19, 131.47), 'Tokushima': (34.07, 134.56),
        'Kagawa': (34.34, 134.04), 'Ehime': (33.84, 132.77), 'Kochi': (33.56, 133.53), 'Fukuoka': (33.61, 130.42),
        'Saga': (33.25, 130.3), 'Nagasaki': (32.74, 129.87), 'Kumamoto': (32.79, 130.74), 'Oita': (33.24, 131.61),
        'Miyazaki': (31.91, 131.42), 'Kagoshima': (31.56, 130.56), 'Okinawa': (26.21, 127.68)}


current_weather_url = 'http://api.openweathermap.org/data/2.5/weather'
forecast_url = 'http://api.openweathermap.org/data/2.5/forecast'
appid = '6dbf61393fba9e88099d19dcdafc6c25' #Please enter your APP ID


def get_current_weather(lat,lon):
#Get weather information
    response = requests.get("{}?lat={}&lon={}&lang=ja&units=metric&APPID={}".format(self.current_weather_url,lat,lon,self.appid))
    return response.json()

def get_tomorrow_weather(lat,lon):
    #Get time today
    today = datetime.today()
    #Get tomorrow's time
    tomorrow = today + timedelta(days=1)
    #Get tomorrow noon time
    tomorrow_noon = datetime.combine(tomorrow, time(12,0))
    #Convert to UNIX time
    timestamp = tomorrow_noon.timestamp()
    #Get weather information
    response = requests.get("{}?lat={}&lon={}&lang=ja&units=metric&APPID={}".format(forecast_url,lat,lon,appid))
    dic = response.json()
    #Loop for weather information every 3 hours
    for i in range(len(dic["list"])):
        #i-th weather information (UNIX time)
        dt = float(dic["list"][i]["dt"])
        #The weather information will be returned when the data becomes data after noon tomorrow.
        if dt >= timestamp:
            return dic["list"][i]
    return ""

def create_db(cur):
    cur.execute('CREATE TABLE test(place STRING,date STRING, type STRING)')

def update_db(cur, text):
    for place in PLACES:
        if place in text:
            cur.execute(f'INSERT INTO test values("{place}","","")')
    for date in DATES:
        if date in text:
            cur.execute(f'INSERT INTO test values("", "{date}", "")')
    for type_ in TYPES:
        if type_ in text:
            cur.execute(f'INSERT INTO test values("", "", "{type_}")')

def read_db(cur):
    cur.execute('SELECT * FROM test')
    data = cur.fetchall()
    place, date, type_ = "","",""
    for p, d, t in data:
        place = p or place
        date = d or date
        type_ = t or type_
    print(place,date,type_)
    return place,date,type_

def clear_db():
    dbname = "weather.db"
    conn = sqlite3.connect(dbname)
    cur = conn.cursor()
    cur.execute('DROP TABLE test')

def reply_000(place,date,type_):
    return 'What are your requirements?'

def reply_001(place,date,type_):
    return 'Please tell me the prefecture and someday (today / tomorrow)'

def reply_011(place,date,type_):
    return 'Please tell me the prefecture'

def reply_100(place,date,type_):
    return 'Please tell me what (weather / temperature) you want to know someday (today / tomorrow)'

def reply_110(place,date,type_):
    return 'What (weather / temperature) do you want to know'

def reply_101(place,date,type_):
    return 'Please tell me someday (today / tomorrow)'

def reply_010(place,date,type_):
    return 'Please tell me what prefecture you want to know (weather / temperature)'

def reply_111(place,date,type_):
    print("place is",place)
    lat = PLACES[place][0] #Get latitude from place
    lon = PLACES[place][1] #Get longitude from place
    print("lat=",lat,"lon=",lon)
    #Clear table
    clear_db()
    if date == "today":
        print("Today's weather forecast")
        cw = get_current_weather(lat,lon)
        if type_ == "weather":
            return(cw["weather"][0]["description"]+"is")
        elif type_ == "temperature":
            return(str(cw["main"]["temp"])+"Degree")
    elif date == "tomorrow":
        tw = get_tomorrow_weather(lat,lon)
        if type_ == "weather":
            return(tw["weather"][0]["description"]+"is")
        elif type_ == "temperature":
            return (str(tw["main"]["temp"])+"Degree")

def start(text):
    dbname = "weather.db"
    conn = sqlite3.connect(dbname)
    cur = conn.cursor()
    if text == "start":
        create_db(cur)
    else:
        update_db(cur,text)
    conn.commit()
    place,date,type_ = read_db(cur)
    print(place,"Dao")
    return place,date,type_

PATTERN = {
    (False,False,False):reply_000,
    (False,False,True):reply_001,
    (False,True,True):reply_011,
    (True,False,False):reply_100,
    (True,True,False):reply_110,
    (True,False,True):reply_101,
    (False,True,False):reply_010,
    (True,True,True):reply_111,
}

def apply(text):
    place, date, type_ = start(text)
    return PATTERN[place!="",date!="",type_!=""](place,date,type_)

main.py


from flask import Flask,request,abort
from linebot import LineBotApi,WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent,TextMessage,TextSendMessage
import os
import requests
import pprint
import w_system

app=Flask(__name__)
#Get environment variables
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]
line_bot_api=LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler=WebhookHandler(YOUR_CHANNEL_SECRET)


@app.route("/callback",methods=["POST"])
def callback():
    print("Callback 1")
    signature=request.headers["X-Line-Signature"]
    print(signature)
    body=request.get_data(as_text=True)
    app.logger.info("Request body"+body)

    try:
        handler.handle(body,signature)
    except InvalidSignatureError:
        abort(400)
    print('Callback')
    return "OK"


@handler.add(MessageEvent,message=TextMessage)
def handle_message(event):
    print('Handle message')
    #Stores the entered character string
    push_text = event.message.text
    reply_text = w_system.apply(push_text)

    #Description of reply part
    line_bot_api.reply_message(event.reply_token,TextSendMessage(text=reply_text))


if __name__=="__main__":
    port=int(os.getenv("PORT",5000))
    app.run(host="0.0.0.0",port=port)

Recommended Posts

I tried to make the weather forecast on the official line by referring to the weather forecast bot of "Dialogue system made with python".
[Python] I asked LINE BOT to answer the weather forecast.
I want to know the weather with LINE bot feat.Heroku + Python
I tried to automatically send the literature of the new coronavirus to LINE with Python
I tried to put out the frequent word ranking of LINE talk with Python
Add a function to tell the weather of today to slack bot (made by python)
I tried to find the entropy of the image with python
I tried to predict the sales of game software with VARISTA by referring to the article of Codexa
I tried to improve the efficiency of daily work with Python
I tried to make my own high school girl BOT with Rinna style with LINE BOT (Python & Heroku)
I tried to verify the speaker identification by the Speaker Recognition API of Azure Cognitive Services with Python. # 1
I tried to verify the speaker identification by the Speaker Recognition API of Azure Cognitive Services with Python. # 2
I tried to summarize the contents of each package saved by Python pip in one line
[Python] I tried to make a simple program that works on the command line using argparse.
[Python] I tried to visualize the night on the Galactic Railroad with WordCloud!
I tried to make "Sakurai-san" a LINE BOT with API Gateway + Lambda
I tried to get the authentication code of Qiita API with Python.
I tried with the top 100 PyPI packages> I tried to graph the packages installed on Python
I tried to verify and analyze the acceleration of Python by Cython
I tried to streamline the standard role of new employees with Python
I tried to get the movie information of TMDb API with Python
I made a weather forecast bot-like with Python.
I tried to open the latest data of the Excel file managed by date in the folder with Python
I tried to make a simple mail sending application with tkinter of Python
I tried to easily visualize the tweets of JAWS DAYS 2017 with Python + ELK
I tried to rescue the data of the laptop by booting it on Ubuntu
[Python] I tried to analyze the characteristics of thumbnails that are easy to play on YouTube by deep learning
I tried to implement Minesweeper on terminal with python
I tried to touch the CSV file with Python
I tried to solve the soma cube with python
I made a LINE BOT with Python and Heroku
I tried to solve the problem with Python Vol.1
I tried to notify the honeypot report on LINE
I tried to summarize the string operations of Python
I tried to make something like a chatbot with the Seq2Seq model of TensorFlow
I tried to automate the article update of Livedoor blog with Python and selenium.
A Python beginner made a chat bot, so I tried to summarize how to make it.
I tried to make it easy to change the setting of authenticated Proxy on Jupyter
I tried to compare the processing speed with dplyr of R and pandas of Python
The 15th offline real-time I tried to solve the problem of how to write with python
I tried to make a function to retrieve data from database column by column using sql with sqlite3 of python [sqlite3, sql, pandas]
I tried "gamma correction" of the image with Python + OpenCV
I tried to simulate how the infection spreads with Python
I tried to make various "dummy data" with Python faker
I tried to find the average of the sequence with TensorFlow
I tried to notify the train delay information with LINE Notify
I evaluated the strategy of stock system trading with Python.
[Python] I tried to visualize the follow relationship of Twitter
I tried to make GUI tic-tac-toe with Python and Tkinter
I tried changing the python script from 2.7.11 to 3.6.0 on windows10
I tried to divide the file into folders with Python
I tried to automatically generate OGP of a blog made with Hugo with tcardgen made by Go
How to write offline real time I tried to solve the problem of F02 with Python
[Python] I want to make a 3D scatter plot of the epicenter with Cartopy + Matplotlib!
The world's most easy-to-understand explanation of how to make LINE BOT (3) [Linkage with server with Git]
I made a class to get the analysis result by MeCab in ndarray with python
I tried to get the number of days of the month holidays (Saturdays, Sundays, and holidays) with python
I wrote a doctest in "I tried to simulate the probability of a bingo game with Python"
[5th] I tried to make a certain authenticator-like tool with python
Life game with Python [I made it] (on the terminal & Tkinter)
I tried scraping the ranking of Qiita Advent Calendar with Python