Skip to content

Instantly share code, notes, and snippets.

@yui0
Last active February 7, 2024 06:16
Show Gist options
  • Save yui0/1d67aabd2fca6c707ad9509b4a95587d to your computer and use it in GitHub Desktop.
Save yui0/1d67aabd2fca6c707ad9509b4a95587d to your computer and use it in GitHub Desktop.
# -*- coding:utf-8 -*-
# ©2024 Yuichiro Nakada
#
# crontab -e
# 0 7,16 * * * python3 ~/weather_line.py
#
# 絵文字: http://www.shurey.com/memo/emoji.html
from dotenv import load_dotenv
load_dotenv()
import requests
import json
import xml.etree.ElementTree as ET
import os
import datetime
import time
from PIL import Image
from io import BytesIO
# 緯度と経度
#lat = '36.05'
#lon = '139.5'
#city_name = '大阪'
lat = os.environ['LAT']
lon = os.environ['LON']
city_name = os.environ['CITY']
# 天気予報を取得
# https://www.arcgis.com/apps/mapviewer/index.html?layers=7b5fe15e303a45c799ccdf353031ef22&layerId=0
#jma_url = "https://weather.tsukumijima.net/api/forecast/city/220040"
def get_weather_forecast():
xml_url = 'https://weather.tsukumijima.net/primary_area.xml'
base_url ='https://weather.tsukumijima.net/api/forecast/'
xml_file = requests.get(xml_url).text
root = ET.fromstring(xml_file)
city_id_dict={}
for value in root.iter('city'):
city_id_dict[value.attrib['title']] = value.attrib['id']
res = requests.get(os.path.join(base_url, 'city', city_id_dict[city_name]))
if res.status_code == 200:
return res.json()
else:
return None
def get_weather_forecast_text(jma_json, n):
jma_date = jma_json["forecasts"][n]["dateLabel"]
jma_weather = str(jma_json["forecasts"][n]["telop"])
jma_rainfall_1 = str(jma_json["forecasts"][n]["chanceOfRain"]["T00_06"])
jma_rainfall_2 = str(jma_json["forecasts"][n]["chanceOfRain"]["T06_12"])
jma_rainfall_3 = str(jma_json["forecasts"][n]["chanceOfRain"]["T12_18"])
jma_rainfall_4 = str(jma_json["forecasts"][n]["chanceOfRain"]["T18_24"])
jma_max = str(jma_json["forecasts"][n]["temperature"]["max"]["celsius"])
jma_min = str(jma_json["forecasts"][n]["temperature"]["min"]["celsius"])
jma_weather = jma_weather.replace(' ', '') # 全角スペースの削除
text = jma_date + "の天気: " + jma_weather + "\n"
text += "最高気温: " + jma_max + "℃\n"
text += "最低気温: " + jma_min + "℃\n"
text += "0時-6時: " + jma_rainfall_1 + "\n"
text += "6時-12時: " + jma_rainfall_2 + "\n"
text += "12時-18時: " + jma_rainfall_3 + "\n"
text += "18時-24時: " + jma_rainfall_4 + "\n\n"
return text
jma_json = get_weather_forecast()
message = "🌏 " + city_name + " ☀⛅☁⚡☔❄⛄🌀\n\n"
message += get_weather_forecast_text(jma_json, 0) # 今日
message += get_weather_forecast_text(jma_json, 1) # 明日
message += jma_json['description']['text'].replace(' ', '') + "\n\n"
#print(message)
#https://qiita.com/bunchospace/items/15aa5c1c467d62cb2423
#https://himawari8.nict.go.jp/img/D531106/4d/550/2024/02/06/030000_1_0.png
#https://himawari8.nict.go.jp/img/D531106/thumbnail/550/2024/02/06/030000_0_0.png
weathercode = {
0 : "☀",
1 : "☀/☁",
2 : "☀/☁",
3 : "☀/☁",
45 : "🌫️",
48 : "🌫️",
51 : "☂",
53 : "☂",
55 : "☂",
56 : "☂",
57 : "☂",
61 : "☔",
63 : "☔",
65 : "☔",
66 : "☔",
67 : "☔",
71 : "☔",
73 : "☔",
75 : "☔",
77 : "☔",
80 : "☂",
81 : "☂",
82 : "☂",
85 : "❄",
86 : "❄",
95 : "⛈",
96 : "⛈",
99 : "⛈",
}
def get_weather_forecast_open_meteo(lat, lon):
# 現在の時間を取得しTZをTokyoとする
tokyo_tz = datetime.timezone(datetime.timedelta(hours=9))
dt = datetime.datetime.now(tokyo_tz)
daily_url = "https://api.open-meteo.com/v1/forecast?latitude=" + lat + "&longitude=" + lon + "&daily=weather_code,temperature_2m_max,temperature_2m_min,precipitation_probability_max&timezone=Asia%2FTokyo"
json_data = requests.get(daily_url)
#print(json_data.json())
i = 0
Date = []
Weather = []
Temp_max = []
Temp_min = []
Pops_max = []
for i in range(7):
# 日付
date = [str(json_data.json().get('daily').get('time')[i])]
Date = Date + date
# 天気
weather = [weathercode[int(json_data.json().get('daily').get('weather_code')[i])]]
Weather = Weather + weather
# 最高気温
temp_max = [str(json_data.json().get('daily').get('temperature_2m_max')[i])]
Temp_max = Temp_max + temp_max
# 最低気温
temp_min = [str(json_data.json().get('daily').get('temperature_2m_min')[i])]
Temp_min = Temp_min + temp_min
# 最大降水確率
pops_max = [str(json_data.json().get('daily').get('precipitation_probability_max')[i])]
Pops_max = Pops_max + pops_max
# 出力
j = 0
text = ''
for j in range(7):
text += "[" + Date[j] + "]\n"
text += " " + Weather[j] + "\n"
text += " 温度(C): " + Temp_max[j] + "/" + Temp_min[j] + "\n"
text += " 最大降水確率(%): " + Pops_max[j] + "\n"
return text
message += get_weather_forecast_open_meteo(lat, lon)
print(message)
# https://emotionexplorer.blog.fc2.com/blog-entry-365.html
def getHimawariImage(band_prod, tail_ary):
# ひまわり衛星写真の画像時刻を気象庁防災情報より取得
url = 'https://www.jma.go.jp/bosai/himawari/data/satimg/targetTimes_jp.json'
r = requests.get(url)
jsn = r.json()
last = jsn[-1]
time.sleep(1)
tail_width = 256 # タイル幅
tail_height = 256 # タイル高
z = 6 # タイル座標(ズーム)
for i, (x, y) in enumerate(tail_ary):
image_url = 'https://www.jma.go.jp/bosai/himawari/data/satimg/{}/jp/{}/{}/{}/{}/{}.jpg'.format(
last['basetime'], last['validtime'], band_prod, z,x,y)
#print(image_url)
# 画像取得
r = requests.get(image_url)
img = Image.open(BytesIO(r.content))
img_name = "/tmp/{}_{}.jpg".format(x, y)
img.save(img_name)
# B13/TBB 赤外画像、B03/ALBD 可視画像、B08/TBB 水蒸気画像、REP/ETC トゥルーカラー再現画像、SND/ETC 雲頂強調画像
#band_prod = 'B13/TBB'
#band_prod = 'B03/ALBD'
band_prod = 'REP/ETC'
#band_prod = 'SND/ETC'
#tail_ary = [[55,24], [56,24], [55,25], [56,25]]
tail_ary = [[55,24], [56,24], [57,24], [55,25], [56,25], [57,25], [55,26], [56,26], [57,26]]
getHimawariImage(band_prod, tail_ary)
def concat_h(img1, img2, color="black"):
# 2枚の画像を横に結合する関数
dst = Image.new(
"RGB",
(img1.width + img2.width, max(img1.height, img2.height)),
color
)
dst.paste(img1, (0, 0))
dst.paste(img2, (img1.width, 0))
return dst
def concat_v(img1, img2, color="black"):
# 2枚の画像を縦に結合する関数
dst = Image.new(
"RGB",
(max(img1.width, img2.width), img1.height + img2.height),
color
)
dst.paste(img1, (0, 0))
dst.paste(img2, (0, img1.height))
return dst
img1 = Image.open("/tmp/55_24.jpg")
img2 = Image.open("/tmp/56_24.jpg")
img3 = Image.open("/tmp/57_24.jpg")
img4 = Image.open("/tmp/55_25.jpg")
img5 = Image.open("/tmp/56_25.jpg")
img6 = Image.open("/tmp/57_25.jpg")
img7 = Image.open("/tmp/55_26.jpg")
img8 = Image.open("/tmp/56_26.jpg")
img9 = Image.open("/tmp/57_26.jpg")
img12 = concat_h(img1, img2, color="white")
img123 = concat_h(img12, img3, color="white")
img45 = concat_h(img4, img5, color="white")
img456 = concat_h(img45, img6, color="white")
img78 = concat_h(img7, img8, color="white")
img789 = concat_h(img78, img9, color="white")
img123456 = concat_v(img123, img456, color="white")
img = concat_v(img123456, img789, color="white")
img.save('/tmp/cloud.jpg')
#img.show()
# https://www.hbc.co.jp/weather/pro-weather.html
r = requests.get('https://www.hbc.co.jp/tecweather/SPAS.jpg')
img = Image.open(BytesIO(r.content))
img.save('/tmp/SPAS.jpg')
# Line
def line_notify(payload, files):
access_token = os.environ['LINE_TOKEN']
url = "https://notify-api.line.me/api/notify"
headers = {'Authorization': 'Bearer ' + access_token}
#payload = {'message': message}
return requests.post(url, headers=headers, params=payload, files=files)
payload = {
'message': message,
'stickerPackageId': 8515,
'stickerId': 16581244,
}
files = {
'imageFile': open('/tmp/cloud.jpg', 'rb')
}
line_notify(payload, files)
payload = {
'message': 'HBC天気図',
}
files = {
'imageFile': open('/tmp/SPAS.jpg', 'rb'),
}
line_notify(payload, files)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment