[PYTHON] J'ai créé un Linebot qui m'informe des sites d'évacuation à proximité sur AWS

introduction

Cet article est "Programmer pour vous empêcher de mourir", Et j'avais l'intention de construire presque le même système en utilisant AWS comme backend. Veuillez vous référer à l'article original pour le contenu détaillé du système.

Je souhaite également créer un système qui aidera avec les contre-mesures en cas de catastrophe et les conseils d'évacuation, et je prévois de publier des articles sur «le système de conseil en cas de catastrophe à l'aide de drones» et le «système de conseil en évacuation à l'aide de haut-parleurs intelligents». J'espère que vous pouvez le voir aussi.

Public cible

Production

友だち追加

En fin de compte, je pensais construire un système de drone, alors ne vous inquiétez pas du fait que l'icône soit un drone. Lorsque vous envoyez les informations de localisation, les sites d'évacuation environnants seront retournés. (Depuis le 13 novembre 2019, seuls les sites d'évacuation de l'est du Japon sont pris en charge m_ _m)

Données du site d'évacuation

Les données sur les sites d'évacuation dans tout le pays sont tirées d'ici. Veuillez télécharger au format json. (https://www.geospatial.jp/ckan/dataset/hinanbasho/resource/5fe3d23c-03fb-49ee-8a65-4f7495a8ea40) Après cela, convertissez-le en fichier CSV en vous référant à l'article d'origine. Cela facilitera le traitement ultérieur avec Pandas en Python.

À propos de la configuration du backend

Un schéma de configuration simple de ce bot LINE est présenté ci-dessous. スクリーンショット 2019-11-13 0.18.48.png

Pour ceux qui découvrent AWS, voici quelques services importants qui sont souvent utilisés dans AWS. Amazon API Gateway C'est un moyen de lier des services externes à AWS. Ici, nous recevons des données de demande webhookées par l'action de la salle de conversation LINE Amazon S3 Stockage qui stocke les données. Quelque chose comme Google Drive. Des souvenirs en termes humains. Les données CSV du site d'évacuation créées précédemment seront saisies ici. AWS lambda Un lieu qui traite les données de demande. serveur. En termes humains, c'est le cerveau. La synchronisation d'exécution de lambda peut être définie et elle peut être déclenchée lorsqu'une demande est envoyée à API Gateway ou lorsque des données sont ajoutées à S3. Ici, les informations de localisation provenant de LINE sont renvoyées afin que les sites d'évacuation à proximité puissent être affichés sur LINE.

Tout ce que vous devez savoir, ce sont ces trois éléments.

la mise en oeuvre

Tout d'abord, vous devez configurer le bot LINE, générer lambda et générer Gateway. Il est indispensable que le compte de développeur LINE et le compte AWS soient préparés à l'avance. L'article suivant est très utile, et j'utilise également AWS et python pour le back-end, donc je pense que c'est une bonne idée de faire quelque chose qui fonctionne en premier. https://xp-cloud.jp/blog/2019/06/24/5560/

En référence à cet article, j'ai implémenté le code lambda comme suit.

import json
import boto3
import urllib
import pyproj
import pandas as pd
import re
import os

#Calcul de la distance entre deux points
def calc_distance(ido1, kdo1, ido2, kdo2):
    g = pyproj.Geod(ellps='WGS84')
    result = g.inv(kdo1, ido1, kdo2, ido2)
    distance = result[2]
    return round(distance)
 
def lambda_handler(event, context):
    url = "https://api.line.me/v2/bot/message/reply"
    method = "POST"
    headers = {
        'Authorization': 'Bearer ' + os.environ['CHANNEL_ACCESS_TOKEN'],
        'Content-Type': 'application/json'
    }
    if event['events'][0]['message']['type'] == 'location':
        s3 = boto3.client('s3')
        bucket_name = 'japan-shelter-all'
        file_name = 'east.csv' 
        response = s3.get_object(Bucket=bucket_name, Key=file_name)
        df = pd.read_csv(response['Body'])
        
        #Cibler les sites d'évacuation à proximité de votre position actuelle
        ido_from = event['events'][0]['message']['latitude'] - 0.05
        ido_to = event['events'][0]['message']['latitude'] + 0.05
        kdo_from = event['events'][0]['message']['longitude'] - 0.05
        kdo_to = event['events'][0]['message']['longitude'] + 0.05
        df_near = df.query(
            f'ido > {ido_from} and ido < {ido_to} and kdo > {kdo_from} and kdo < {kdo_to}'
        )
        
        #Identifiez le site d'évacuation le plus proche de votre emplacement actuel
        min_distance = None
        min_row = None
        for index, row in df_near.iterrows():
            hinan_ido = row['ido']
            hinan_kdo = row['kdo']
            distance = calc_distance(
                event['events'][0]['message']['latitude'], event['events'][0]['message']['longitude'], hinan_ido, hinan_kdo
            )
            if min_distance is None or distance < min_distance:
                min_distance = distance
                min_row = row
        
        if min_distance != None:
            message = [
                {
                    "type": "text",
                    "text": f"{min_row['name']}Évacuons vers"
                },
                {
                    "type": "location",
                    "title": f"Vers le site d'évacuation{min_distance}m",
                    "address": f"{min_row['addr']}",
                    "latitude": f"{min_row['ido']}",
                    "longitude": f"{min_row['kdo']}"
                }
            ]
        else:
            message = [
                {
                    "type": "text",
                    "text": "Aucun abri trouvé à proximité"
                }
            ]
    
    
        params = {
            "replyToken": event['events'][0]['replyToken'],
            "messages": message
        }
        request = urllib.request.Request(url, json.dumps(params).encode("utf-8"), method=method, headers=headers)
        with urllib.request.urlopen(request) as res:
            body = res.read()
    return 0

Même si vous essayez d'exécuter lambda tel quel, une erreur se produira si les bibliothèques externes de pandas et pyproj ne peuvent pas être chargées. La solution est de permettre à ces bibliothèques supplémentaires d'être importées dans lambda au format de couche. Installez ces bibliothèques sur EC2 (machine virtuelle AWS), téléchargez-les sur S3, puis ajoutez-les à la couche. (Si vous souhaitez voir d'autres méthodes ensemble, reportez-vous à [AWS / Lambda] Méthode de chargement de la bibliothèque externe Python) Pour la procédure, reportez-vous à la vidéo YouTube suivante. C'est une vidéo d'outre-mer, mais elle est très facile à comprendre. N'oubliez pas d'installer pyproj ainsi que pandas. https://www.youtube.com/watch?v=zrrH9nbSPhQ

スクリーンショット 2019-11-13 13.29.30.png

Après cela, si vous pouvez importer diverses bibliothèques en toute sécurité, cela réussit.

Résumé

J'ai résumé une procédure simple de LINEbot sur AWS en référence à d'autres articles. Je ne touche généralement pas à AWS moi-même, alors faites-moi savoir si vous devez gérer le fichier CSV dans DB. L'application elle-même a été satisfaite après confirmation de la communication, je ne l'améliorerai donc pas. En guise de suite, nous prévoyons de publier "Disaster Evacuation Advisory System Using Drone" et "Evacuation Advisory System Using Smart Speaker", alors jetez un œil. Si vous trouvez cet article utile ou si vous attendez une suite, veuillez lui donner une note élevée ^ ^

Recommended Posts

J'ai créé un Linebot qui m'informe des sites d'évacuation à proximité sur AWS
J'ai fait un bot mou qui m'informe de la température
J'ai créé un SlackBot qui m'informe chaque semaine des informations sur le concours AtCoder
Avec LINEBot, j'ai fait une application qui m'informe de "l'heure du bus"
J'ai fait un générateur de réseau neuronal qui fonctionne sur FPGA
J'ai fait un Line-bot avec Python!
J'ai créé un nouveau compartiment AWS S3
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber
[Python] J'ai créé un robot qui me dit la température actuelle lorsque j'entre un nom de lieu sur LINE
J'ai créé une extension Chrome qui affiche un graphique sur la page Amedas
J'ai écrit un bot Slack qui notifie les informations de retard avec AWS Lambda
Création d'un bot Slack qui confirme et notifie à AWS Lambda la date d'expiration d'un certificat SSL
[Discode Bot] J'ai essayé de créer un Bot qui me dit la valeur de race de Pokemon
[Python / C] J'ai créé un appareil qui fait défiler sans fil l'écran d'un PC à distance.
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber (édition Google Calendar)
[AWS] J'ai créé un BOT de rappel avec LINE WORKS
J'ai créé une application Twitter qui identifie et enregistre l'image d'un personnage spécifique sur la chronologie de Twitter par pytorch transfer learning
J'ai créé une boîte de changement de seuil pour Pepper's Dialog
J'ai créé une VM qui exécute OpenCV pour Python
J'ai créé un environnement Python3 sur Ubuntu avec direnv.
〇✕ J'ai fait un jeu
Une histoire qui a trébuché lorsque j'ai créé un bot de chat avec Transformer
[Python] Créez un linebot qui dessine n'importe quelle date sur une photo
unixtime ← → J'ai essayé de créer une classe qui effectue facilement la conversion datetime
J'ai fait une fonction pour vérifier le modèle de DCGAN
J'ai fait une putain d'application qui ne te laisse pas sauter
J'ai fait une image ponctuelle de l'image d'Irasutoya. (partie 1)
[Introduction à AWS] Mémorandum de création d'un serveur Web sur AWS
J'ai fait un modèle VGG16 en utilisant TensorFlow (en chemin)
J'ai créé un modèle de détection d'anomalies qui fonctionne sur iOS
J'ai fait une minuterie pomodoro dure qui fonctionne avec CUI
J'ai fait une image ponctuelle de l'image d'Irasutoya. (partie 2)
J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft
[Python3] Liste des sites auxquels j'ai fait référence lorsque j'ai lancé Python
[AWS] J'ai créé un BOT de rappel avec LINE WORKS (implémentation)
J'ai créé un robot Line qui devine le sexe et l'âge d'une personne à partir de l'image
Une histoire que j'ai eu du mal à afficher des graphiques les uns sur les autres avec matplotlib
J'ai créé un bot LINE qui me dit le type et la force de Pokémon dans la région de Garal avec Heroku + Flask + PostgreSQL (Heroku Postgres)