Mein Name ist Niamugi und ich bin verantwortlich für den 4. Tag des IoTLT-Adventskalenders 2019. "Anzeigen der Wettervorhersage auf M5Stack" ist ein sehr solider Inhalt, aber ich möchte ihn einführen, da ein vielseitiger Mechanismus erstellt wurde. ** Es ist beliebt bei meiner Familie und ich bin froh, dass es täglich verwendet wird. ** **.
Zeigt die Wettervorhersage für die letzten 3 Tage an. Das Wetterzeichen wurde von meinem ältesten Sohn geschrieben.
Es wird so angezeigt.
Das Wettervorhersagebild ist in "** generieren " und " erwerben **" unterteilt.
Ich werde die Punkte aufzählen.
Ich erhalte Daten, indem ich auf Wettervorhersage der Wetterbehörde zugreife.
Wenn Cloud-Funktionen, die in der Cloud ausgeführt werden, Ihre Dateien verarbeiten sollen, können Sie sie im Ordner / tmp speichern. Mit anderen Worten, indem Sie die von Google Drive erhaltene Datei im Ordner / tmp speichern, können Sie die Datei auf dieselbe Weise wie in der lokalen Umgebung behandeln.
Besorgen Sie sich die für den Zugriff erforderliche Client-ID, das Client-Geheimnis und das Aktualisierungstoken im Voraus. Ich habe darüber zuvor im Blog von dot studio geschrieben. [Hochladen von Daten von NefryBT auf Google Drive](https://dotstud.io/blog/update-nefrybt-to-googledrive/#%E3%82%A2%E3%83%83%E3%83%97% E3% 83% AD% E3% 83% BC% E3% 83% 89% E3% 81% BE% E3% 81% A7% E3% 81% AE% E6% 89% 8B% E9% A0% 86 )Bitte beziehen Sie sich auf.
Fordern Sie den Dienst auf, mit der Client-ID, dem Client-Geheimnis und dem Aktualisierungstoken auf Google Drive zuzugreifen. Ich bezog mich auf "Python-Aktualisierungstoken Google API: Anmeldeinformationen vom Aktualisierungstoken mithilfe von oauth2client.client abrufen".
def getDriveService():
CLIENT_ID = os.getenv("drive_client_id")
CLIENT_SECRET = os.getenv("drive_client_secret")
REFRESH_TOKEN = os.getenv("drive_refresh_token")
creds = client.OAuth2Credentials(
access_token=None,
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
refresh_token=REFRESH_TOKEN,
token_expiry=None,
token_uri=GOOGLE_TOKEN_URI,
user_agent=None,
revoke_uri=None,
)
http = creds.authorize(httplib2.Http())
creds.refresh(http)
service = build("drive", "v3", credentials=creds, cache_discovery=False)
return service
Allen Daten in Google Drive werden IDs zugewiesen. Die ID-Suche ist erforderlich, um Daten anhand der ID zu erfassen und zu aktualisieren.
def searchID(service, mimetype, nm):
"""Suchen Sie eine passende ID von Drive
"""
query = ""
if mimetype:
query = "mimeType='" + mimetype + "'"
page_token = None
while True:
response = (
service.files()
.list(
q=query,
spaces="drive",
fields="nextPageToken, files(id, name)",
pageToken=page_token,
)
.execute()
)
for file in response.get("files", []):
if file.get("name") == nm:
return True, file.get("id")
page_token = response.get("nextPageToken", None)
if page_token is None:
break
Cloud-Funktionen werden in der Cloud ausgeführt, sodass Sie wahrscheinlich keine japanischen Schriftarten verwenden können. (Ich habe es nicht versucht) Holen Sie sich also die Schriftart von Google Drive. Der Mimetyp ist "application / octat-stream".
def getFontFromDrive(service, fontName):
"""Holen Sie sich Schriftarten von Drive und speichern Sie sie im tmp-Ordner
"""
ret, id = searchID(service, "application/octet-stream", fontName)
if not ret:
return None
request = service.files().get_media(fileId=id)
fh = io.FileIO("/tmp/" + fontName, "wb") #Datei
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
return "/tmp/" + fontName
Holen Sie sich das Wetterzeichen. Mimetyp ist "image / png".
def getImageFromDrive(service, imageName):
"""Holen Sie sich das Image von Drive und speichern Sie es im tmp-Ordner
"""
ret, id = searchID(service, "image/png", imageName)
if not ret:
return False
request = service.files().get_media(fileId=id)
fh = io.FileIO("/tmp/" + imageName, "wb") #Datei
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
return True
Laden Sie das generierte Wettervorhersagebild auf Google Drive hoch.
def uploadData(service, mimetype, fromData, toData, parentsID="root"):
"""Auf Laufwerk hochladen
"""
try:
media = MediaFileUpload(fromData, mimetype=mimetype, resumable=True)
except FileNotFoundError:
return False
#Suchen Sie nach ID und überschreiben Sie diese, wenn zutreffende Daten vorhanden sind.
ret, id = searchID(service, mimetype, toData)
if ret:
file_metadata = {"name": toData}
file = (
service.files()
.update(fileId=id, body=file_metadata, media_body=media, fields="id")
.execute()
)
else:
file_metadata = {"name": toData, "parents": [parentsID]}
file = (
service.files()
.create(body=file_metadata, media_body=media, fields="id")
.execute()
)
return True
Verwenden Sie die oben vorbereitete Funktion, um das Wettervorhersagebild auf Google Drive hochzuladen.
def CreateImgWeather(event, context):
""" get weatherImage and upload to drive for M5stack
"""
# 1.Holen Sie sich einen Dienst, um auf Google Drive zuzugreifen
driveService = getDriveService()
# 2.Schriftart abrufen
fontPath = getFontFromDrive(driveService, "meiryo.ttc")
if not fontPath:
return False
# 3.Holen Sie sich das Wetterzeichen
if not getImageFromDrive(driveService, "noImage.png "):
return False
if not getImageFromDrive(driveService, "fine.png "):
return False
if not getImageFromDrive(driveService, "cloud.png "):
return False
if not getImageFromDrive(driveService, "rain.png "):
return False
if not getImageFromDrive(driveService, "snow.png "):
return False
# 4.Wettervorhersagebild generieren
weatherList = getWeekWeather()
ret = createImg(fontPath, "/tmp/imgWeather.jpeg ", weatherList)
if not ret:
return False
# 5.Auf Google Drive hochladen
ret = uploadData(
driveService, "image/jpeg", "/tmp/imgWeather.jpeg ", "imgWeather.jpeg "
)
if not ret:
return False
return True
Weitere Informationen finden Sie unter Quelle.
Zugriff auf Cloud-Funktionen funktioniert mit einer http-POST-Anforderung. Dies ist auch dotstudios "Anfrage über HTTP-Kommunikation senden" Ich habe es als Referenz verwendet.
[Hostname] = "[Projektname].cloudfunctions.net"
[Funktionsname] = "getDriveImage_M5stack";
[Port-Nummer] = 443;
POST /[Funktionsname] HTTP/1.1
Host: [Hostname]:[Port-Nummer]
Connection: close
Content-Type: application/json;charset=utf-8
Content-Length: + [Größe der zu postenden JSON-Daten]
[Json Daten zu posten]
Stellen Sie die folgende Anfrage im JSON-Datenformat.
{
"drive" : {
"img" : "[Dateiname]",
"trim" : "[Geteilte Nummer]"
}
}
Aufgrund der Datenmenge, die gleichzeitig erfasst werden kann, ist sie in 8 Teile unterteilt. Daher wird 8 Mal eine POST-Anfrage gestellt.
Erfasst das Wettervorhersagebild gemäß der POST-Anforderung von M5Stack. Dann werden die in 8 Teile unterteilten Binärdaten zurückgegeben.
Ich werde die Quelle setzen.
import sys
import os
import io
from io import BytesIO
import numpy as np
from PIL import Image
import httplib2
from googleapiclient.discovery import build
from oauth2client import client, GOOGLE_TOKEN_URI
from apiclient.http import MediaIoBaseDownload
def getDriveService():
~Gleich wie Bilderzeugung~
def searchID(service, mimetype, nm):
~Gleich wie Bilderzeugung~
def downloadData(mimetype, data):
#Holen Sie sich einen Dienst, um auf Google Drive zuzugreifen
drive_service = getDriveService()
#Suche nach ID
ret, id = searchID(drive_service, mimetype, data)
if not ret:
return False, None
#Suchen Sie nach Wettervorhersagebildern
request = drive_service.files().get_media(fileId=id)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
return True, fh.getvalue()
def devideImage_M5stack(imgBinary, _trim):
"""Teilen Sie das Bild für M5Stack. Der Rückgabewert sind Bilddaten
"""
imgNumpy = 0x00
#Bestätigung der Eingabedaten
if _trim.isnumeric():
trimPos = int(_trim)
if trimPos <= 0 or trimPos > 8:
return False
else:
return False
#Bildaufteilung
# 1 2 3 4
# 5 6 7 8
Trim = [
(0, 0, 80, 120),
(80, 0, 160, 120),
(160, 0, 240, 120),
(240, 0, 320, 120),
(0, 120, 80, 240),
(80, 120, 160, 240),
(160, 120, 240, 240),
(240, 120, 320, 240),
]
#PIL-Bild<-Binärdaten
img_pil = Image.open(BytesIO(imgBinary))
#Trimmen
im_crop = img_pil.crop(Trim[trimPos - 1])
#numpy Array(RGBA) <-PIL-Bild
imgNumpy = np.asarray(im_crop)
return True, imgNumpy
def getBinary(img):
"""Konvertieren Sie Bilder in Binärdaten
"""
ret = ""
pilImg = Image.fromarray(np.uint8(img))
output = io.BytesIO()
pilImg.save(output, format="JPEG")
ret = output.getvalue()
return ret
def getDriveImg_Binary(imgName, trim):
"""Holen Sie sich das Bild in googleDrive gespeichert. Der Rückgabewert sind Binärdaten.
"""
img = 0x00
#Bild vom Laufwerk(Binärdaten)Erhalten
ret, imgBinary = downloadData("image/jpeg", imgName)
if not ret:
print("...error")
return ""
print(ret, len(imgBinary))
#Teilen Sie das Bild
#* Nur für M5-Stapel
if trim is not None:
isGet, img = devideImage_M5stack(imgBinary, trim)
if not isGet:
return ""
#In Binärdaten konvertieren
imgBinary = getBinary(img)
return imgBinary
def getDriveImage_M5stack(request):
imgName = ""
trim = "0"
#Daten anfordern(JSON)Konvertieren
request_json = request.get_json()
#Erhalten Sie Zugriffsinformationen zu Google Drive
if request_json and "drive" in request_json:
imgName = request_json["drive"]["img"]
trim = request_json["drive"]["trim"]
else:
return ""
#Holen Sie sich ein getrimmtes Wettervorhersagebild
ret = getDriveImg_Binary(imgName, trim)
return ret
Das Gute an diesem Mechanismus ist, dass "** Sie können es auf M5Stack anzeigen, wenn Sie ein Bild vorbereiten **". Mit anderen Worten, es ist nicht auf Wettervorhersagen beschränkt, sondern kann alles wie Zeitpläne und Aufgaben verarbeiten. Legen Sie auf der M5Stack-Seite einfach den zu erfassenden Bildnamen fest. Da das Bild außerhalb von M5Stack generiert wird, müssen Sie das M5Stack-Programm nicht berühren, wenn Sie das Bild ändern möchten.
Das folgende Muster zeigt den Google-Kalender an. (Der Zeitplan ist Mosaik)
Durch die Erstellung eines Bildanzeigesystems, das diesmal zu M5Stack passt, habe ich mir einige Anwendungsmuster überlegt. Das Display von M5Stack hat genau die richtige Größe für den Tisch, daher möchte ich es auf verschiedene Arten verwenden.
Ich hoffe es wird für Sie hilfreich sein. Bis bald.
[Hochladen von Daten von NefryBT auf Google Drive](https://dotstud.io/blog/update-nefrybt-to-googledrive/#%E3%82%A2%E3%83%83%E3%83%97% E3% 83% AD% E3% 83% BC% E3% 83% 89% E3% 81% BE% E3% 81% A7% E3% 81% AE% E6% 89% 8B% E9% A0% 86 ) Python-Aktualisierungstoken Google API: Verwenden Sie oauth2client.client, um Anmeldeinformationen vom Aktualisierungstoken abzurufen Anfrage über HTTP-Kommunikation senden
Recommended Posts