Everyone has once left an umbrella in a company or school, right? If it rains the next day, I'm in despair without an umbrella. .. ..
Therefore, we have created a system that notifies LINE so that you will not forget your umbrella when you return home **!
It is based on the system introduced in the following article that notifies you to have an umbrella in the morning if it rains.
Python + AWS Lambda + Line Notify automatically notifies Line of today's weather every morning.
Implemented in addition to the above, ** Notify you to bring an umbrella in the morning if it rains ** + ** Notify you to bring your umbrella home when you get home ** Support rainy days!
First, launch Lambda at 7am every morning in CloudWatch Event. Lambda gets the weather information and tells LINE to have an umbrella if it rains today. Up to this point, you can create it with above article.
The difference is that if it rains, it will create a file in S3. This is used for notification when returning home.
This is the main part added in this article. First, launch Lambda every day when you get home with CloudWatch Event. Lambda will check S3, and if the file was created on today's date, it will determine that you have an umbrella in the morning and will notify LINE to bring it back.
It's very simple! Let's actually make it!
Get the LINE Notify token by referring to the following articles. https://qiita.com/iitenkida7/items/576a8226ba6584864d95
Create an appropriate directory in your S3 bucket.
In this article, we created the weather
directory.
In the system of this article, the following files will be generated in the directory created above. In addition, since the deletion process is not implemented, it is convenient to set the life cycle rule and delete it automatically after a few days!
Create a new Lambda function. This time, the runtime is Python 3.8.
Edit the default generated lambda_function.py
and paste the code below.
lambda_function.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import sys
import urllib.parse
import urllib.request
import datetime
import os
import boto3
# weather's API
WEATHER_URL="http://weather.livedoor.com/forecast/webservice/json/v1?city=%s"
CITY_CODE="130010" # TOKYO
TODAY=0
# LINE notify's API
LINE_TOKEN = os.environ['LINE_TOKEN']
LINE_NOTIFY_URL = "https://notify-api.line.me/api/notify"
S3_BUCKET_NAME = os.environ['S3_BUCKET_NAME']
S3_PREFIX = "weather/"
s3 = boto3.resource('s3')
s3Client = boto3.client('s3')
def get_weather_info():
try:
url = WEATHER_URL % CITY_CODE
html = urllib.request.urlopen(url)
html_json = json.loads(html.read().decode('utf-8'))
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)
return html_json
def set_weather_info(weather_json, day):
min_temperature = None
max_temperature = None
try:
date = weather_json['forecasts'][day]['date']
weather = weather_json['forecasts'][day]['telop']
max_temperature = weather_json['forecasts'][day]['temperature']['max']['celsius']
min_temperature = weather_json['forecasts'][day]['temperature']['min']['celsius']
except TypeError:
# temperature data is None etc...
pass
msg = "%s\nweather: %s\nmin: %s\nmax: %s" % \
(date, weather, min_temperature, max_temperature)
return msg
def send_info(msg):
method = "POST"
headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
payload = {"message": msg}
try:
payload = urllib.parse.urlencode(payload).encode("utf-8")
req = urllib.request.Request(
url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
urllib.request.urlopen(req)
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)
def put_s3():
now = datetime.datetime.now() + datetime.timedelta(hours=9) ## UTC+9
obj = s3.Object(S3_BUCKET_NAME, S3_PREFIX + now.strftime('%Y-%m-%d'))
obj.put()
def was_it_raining():
now = datetime.datetime.now() + datetime.timedelta(hours=9) ## UTC+9
contents = s3Client.list_objects(Bucket=S3_BUCKET_NAME, Prefix=S3_PREFIX)["Contents"]
if contents:
for content in contents:
if content.get("Key") == S3_PREFIX + now.strftime('%Y-%m-%d'):
return True
return False
def lambda_handler(event, context):
if('event_type' not in event):
return {
'statusCode': 400,
'body': json.dumps('event_type does not exist in event')
}
if(event['event_type'] == "morning"):
weather_json = get_weather_info()
msg = set_weather_info(weather_json, TODAY)
if("rain" in weather_json['forecasts'][0]['telop']):
send_info("\n☔☔☔☔☔☔☔☔\n It will rain today.\n Don't forget your umbrella!\n☔☔☔☔☔☔☔☔" + msg)
put_s3()
elif(event['event_type'] == "evening" and was_it_raining()):
send_info("\n☂️☂️☂️☂️☂️☂️☂️☂️\n Let's take an umbrella home!\n☂️☂️☂️☂️☂️☂️☂️☂️")
return {
'statusCode': 200,
'body': json.dumps('function finished')
}
Create two triggers in your CloudWatch Event to launch your Lambda in the morning (7:00) and when you get home (17:00). On the Lambda function screen, click "Add Trigger" in the red frame below.
Select CloudWatch Event and create two triggers with a scheduled expression like this:
cron (0 22 * *? *)
→ Starts every day at 7:00 (UTC 22:00)cron (0 8 * *? *)
→ Starts every day at 17:00 (UTC 8 o'clock)Click the created event to display the edit screen. Then set the value to pass when triggering Lambda as follows.
{"event_type": "morning"}
{"event_type": "evening"}
This will pass the value set above to the event variable of lambda_handler when each trigger starts Lambda. In Lambda of this article, by conditional branching with this value, the morning processing and the processing at the time of returning home are separated as follows. Convenient!
def lambda_handler(event, context):
if(event['event_type'] == "morning"):
#Morning processing
elif(event['event_type'] == "evening"):
#Processing when returning home
That's it! Let's wait for a rainy day!
Notifications came to LINE on rainy days, morning and when I got home! Thanks to that, I feel that I'm less likely to forget my umbrella and leave it on the go.
You can make it with the AWS free frame, so please give it a try.
Recommended Posts