Neulich wurde "Amazon Dash Button" endlich in Japan veröffentlicht. Der Punkt ist, dass wenn Sie auf die Schaltfläche klicken, das Zielprodukt automatisch von Amazon bestellt und zu Ihnen nach Hause geliefert wird. Machen wir das diesmal selbst! Es ist ein Artikel in diesem Sinne.
Diejenigen, die es verstehen, werden verstehen, aber um genau zu sein, diejenigen, die "AWS IoT Button" sagen, eine programmierbare Version von "Amazon Dash Button". Ich denke es ist nah.
Die Gesamtarchitektur ist wie folgt:
Ich werde dies im Hintergrund des Prozesses ausführlich erläutern (in der Reihenfolge 3-> 2-> 1).
In diesem Kapitel werden wir Selenium und PhantomJS verwenden, um die Amazon-Website zu crawlen und eine Lambda-Funktion zu erstellen, die den angegebenen Artikel automatisch kauft.
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html Wenn AWS Lambda Code in AWS Lambda hochlädt, wird der Service zu einem Computerdienst, der die AWS-Infrastruktur verwendet, um die Ausführung des Codes zu übernehmen.
Java, Node.js, Python, C # können für die Laufzeit ausgewählt werden, aber dieses Mal werden wir Python verwenden.
Platzieren Sie den Lambda-Funktionskörper und die erforderlichen Bibliotheken direkt unter dem Projektverzeichnis.
$ tree -L 1
.
├── amzorderer.py #Lambda-Funktionskörper
├── phantomjs #PhantomJS binär
├── selenium #Selenium-Bibliothek für Python
└── selenium-3.0.2.dist-info
Referenz: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html
Installieren Sie Selenium mit pip direkt unter dem Projektverzeichnis.
pip install selenium -t /path/to/project-dir
Laden Sie die Linux 64-Bit-Version von tar von PhantomJS Official herunter und platzieren Sie phantomjs im bin-Verzeichnis direkt unter dem Projektverzeichnis.
Der Quellcode ist auch unten verfügbar. (Geplant, später veröffentlicht zu werden)
amzorderer.py
# -*- coding:utf-8 -*-
__author__ = 'H.Takeda'
__version__ = '1.0.0'
import os
import boto3
from argparse import ArgumentParser
from base64 import b64decode
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# Amazon top page url.
AMAZON_URL = "https://www.amazon.co.jp"
# Amazon user id (email).
AMAZON_USER = boto3.client('kms').decrypt(
CiphertextBlob=b64decode(os.environ['user']))['Plaintext']
# Amazon user password.
AMAZON_PASS = boto3.client('kms').decrypt(
CiphertextBlob=b64decode(os.environ['password']))['Plaintext']
# User agent.
USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 (KHTML, like Gecko) Chrome/15.0.87"
# Item dictionary.
ITEMS = {
"01": "1fLhF7q", # Toilet Paper
"02": "fhYcbp7" # Saran Wrap
}
def lambda_handler(event, context):
# Create web driver for PhantomJS.
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = USER_AGENT
driver = webdriver.PhantomJS(desired_capabilities=dcap,
service_log_path=os.path.devnull,
executable_path="/var/task/phantomjs")
# Get amazon top page.
driver.get(AMAZON_URL)
# Transition to sign in page.
driver.find_element_by_id("nav-link-yourAccount").click()
# Input user id.
driver.find_element_by_id("ap_email").send_keys(AMAZON_USER)
# Input user password.
driver.find_element_by_id("ap_password").send_keys(AMAZON_PASS)
# Sign in.
driver.find_element_by_id("signInSubmit").click()
# Select item.
driver.get("http://amzn.asia/" + ITEMS[event["item"]])
# Add to cart.
driver.find_element_by_id("add-to-cart-button").click()
# Proceed to checkout.
driver.find_element_by_id("hlb-ptc-btn-native").click()
# Order.
# driver.find_element_by_name("placeYourOrder1")[0].click()
driver.save_screenshot("hoge.png ")
driver.quit()
Grundsätzlich mache ich nur eine einfache Selen-Operation, aber ich werde die Punkte aufgreifen.
ghostdriver.log
) standardmäßig im aktuellen Verzeichnis erstellt wird, geben Sie es nicht aus (/ dev / null).Zippen Sie das Projektverzeichnis. Der Name der Zip-Datei spielt keine Rolle.
$ zip -r upload.zip /path/to/project-dir/*
Stellen Sie die Lambda-Funktion über die AWS-Verwaltungskonsole ein. Sie können die erstellte Zip-Datei auch hier hochladen.
Stellen Sie das Testereignis (Parameter, der an die Lambda-Funktion übergeben wurde) unter Aktionen> Testereignis konfigurieren ein. Drücken Sie die Test-Taste, um die Lambda-Funktion auszuführen.
Es ist in Ordnung, wenn der Vorgang normal abgeschlossen ist. Damit ist die Erstellung der Lambda-Funktion abgeschlossen, die automatisch bei Amazon gekauft wird.
In diesem Kapitel verwenden wir AWS IoT, um MQTT-Anforderungen zu akzeptieren und die Einstellungen zum Aufrufen der oben erstellten Lambda-Funktion zu konfigurieren.
https://aws.amazon.com/jp/iot/how-it-works/ Durch die Verwendung von AWS IoT ist es möglich, verschiedene Geräte mit verschiedenen AWS-Diensten zu verbinden, Daten und Kommunikation zu schützen sowie Verarbeitung und Aktionen für Gerätedaten durchzuführen.
Registrieren Sie das Gerät, das eine Verbindung zu AWS IoT herstellt, über den Bildschirm der AWS IoT-Konsole.
2. Wählen Sie die Umgebungsinformationen für das Clientgerät aus. Dieses Mal stellen wir über das Python SDK eine Verbindung zu AWS IoT von Raspberry Pi Zero (OS: Raspbian) her.
3. Geben Sie einen beliebigen Gerätenamen ein (in diesem Fall raspi0) und klicken Sie auf "Nächster Schritt".
4. Drücken Sie "Liux / OSX", um den öffentlichen Schlüssel, den privaten Schlüssel und das Client-Zertifikat herunterzuladen (Sie werden sie später verwenden). Klicken Sie auf "Nächster Schritt", um zum nächsten Bildschirm zu gelangen.
5. Die Geräteeinstellung wird angezeigt. Drücken Sie zum Abschluss "Fertig".
Legen Sie fest, dass die Lambda-Funktion aufgerufen wird, wenn eine Nachricht zu einem bestimmten Thema veröffentlicht wird.
2. Geben Sie einen beliebigen Regelnamen ein (in diesem Fall amzorderer), um die Regelabfrage festzulegen. Wenn eine Nachricht im Thema "amzordere" veröffentlicht wird, extrahiert sie den Wert des Elementattributs und führt die Aktion aus.
3. Wählen Sie Call Lambda-Funktion als Aktion.
4. Die aufzurufende Funktion ist der zuvor erstellte "amzorderer".
5. Klicken Sie auf "Regel erstellen", um die Erstellung abzuschließen.
In diesem Kapitel verwenden wir Raspberry Pi, um ein Client-Gerät mit Schaltflächen zu erstellen.
Unnötig zu sagen, dass es ein kleines Modell von Razpai sein wird. Mit einem CPU-Takt von 1 GHz und einem Speicher von 512 MB ist der Preis mit etwa 5 US-Dollar außergewöhnlich hoch. Diesmal mit diesem Raspberry Pi Zero, Ich möchte ein Gerät erstellen, das auf Knopfdruck eine Anfrage an AWS IoT sendet.
Wir werden es mit grundlegenden elektronischen Arbeitsteilen machen, die in jedem Haushalt zu finden sind.
Da es nur ein Mini-USB-Terminal gibt, ist es praktisch, zum Zeitpunkt der Ersteinstellung einen USB-Hub zu haben.
Installieren Sie Raspbian (Jessie) unter Around here.
Dieses Mal werden wir Raspberry Pi Zero über die drahtlose Slave-Einheit von Buffalo mit dem WLAN verbinden.
Schließen Sie die WLAN-Slave-Einheit an USB an.
Wenn Sie den Befehl lsusb
eingeben, können Sie sehen, dass er die Slave-Einheit erkennt.
$ lsusb
Bus 001 Device 002: ID 0411:01a2 BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Verwenden Sie den Befehl wpa_passphrase
, um die für eine WLAN-Verbindung erforderliche SSID und das Kennwort zu generieren.
$ wpa_passphrase [SSID] [Passphrase]
network={
ssid=[SSID]
#psk=[Passphrase] <-Sie können diese Zeile löschen
psk=[Verschlüsselte Passphrase]
}
Kopieren Sie den obigen Text und fügen Sie ihn zu / etc / wpa_supplicant / wpa_supplicant.conf
hinzu.
/etc/wpa_supplicant/wpa_supplicant.conf
country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid=[SSID]
psk=[Verschlüsselte Passphrase]
}
Bearbeiten Sie / etc / dhcpcd.conf
und machen Sie es zu einer festen IP.
Stellen Sie die IP-Adresse, den Router und das DNS entsprechend Ihrer Umgebung ein.
interface wlan0
static ip_address=192.168.11.30/24
static routers=192.168.11.1
static domain_name_servers=192.168.11.1
Wenn Sie die SSH-Verbindung vom Mutterschiff aus neu starten können, ist die Einstellung abgeschlossen.
$ sudo shutdown -r now
Im Gegensatz zu anderen Modellen ist bei Verwendung von GPIO mit Raspberry Pi Zero das Löten erforderlich. Es wird eine feinere Arbeit sein als ich erwartet hatte, daher ist es besser, eine Lötausrichtung von φ0,6 mm zu verwenden.
Ehrlich gesagt ist elektronische Arbeit ein Amateur, aber ich werde sie unter Bezugnahme auf die Informationen erstellen, die ich im Internet gesucht habe. Das GPIO-Layout von Raspberry Pi Zero ist wie folgt.
Es nimmt eine Stromversorgung von 3,3 V von Nr. 1 und empfängt das Ein- und Ausschalten des GPIO25-Taktschalters bei GPIO9. Stecken Sie einen 10k Ohm Widerstand zwischen GPIO25 und GND. Dies wird als Pulldown-Widerstand bezeichnet und spielt eine Rolle bei der zuverlässigen Übertragung eines HIGH- (3,3 V) oder LOW- (0 V) Signals. Es tut mir leid, dass das Bild schwer zu verstehen ist.
Nachdem die Schaltung zusammengebaut ist, erstellen wir ein Programm, das die Eingabe des Taktschalters empfängt und die Nachricht an AWS IoT veröffentlicht.
Python 2.7 ist in Raspbian (Jessie) installiert, daher werde ich das Programm in Python schreiben.
$ python -V
Python 2.7.9
Das Python SDK für die Verbindung mit AWS IoT ist für die Öffentlichkeit zugänglich und wird verwendet.
$ sudo pip install AWSIoTPythonSDK
publisher.py
# -*- coding:utf-8 -*-
__author__ = 'H.Takeda'
__version__ = '1.0.0'
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
from argparse import ArgumentParser
import json
import logging
import RPi.GPIO as GPIO
import signal
import sys
import time
def configure_logging():
# Configure logging
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)
def parse():
argparser = ArgumentParser()
argparser.add_argument("-e", "--endpoint", type=str, required=True)
argparser.add_argument("-r", "--rootCA", type=str, required=True)
argparser.add_argument("-c", "--cert", type=str, required=True)
argparser.add_argument("-k", "--key", type=str, required=True)
args = argparser.parse_args()
return vars(args)
def careate_client(endpoint, root_ca, cert, private_pey):
# For certificate based connection.
client = AWSIoTMQTTClient("raspi0")
# Configurations
client.configureEndpoint(endpoint, 8883)
client.configureCredentials(root_ca, private_pey, cert)
client.configureOfflinePublishQueueing(1)
client.configureConnectDisconnectTimeout(10) # 10 sec
client.configureMQTTOperationTimeout(5) # 5 sec
return client
def handler(signum, frame):
print "Signal handler called with signal", signum
client.disconnect()
GPIO.cleanup()
sys.exit(0)
if __name__ == '__main__':
# Parse command-line arguments.
args = parse()
# Configure logging
configure_logging()
# Create mqtt client.
client = careate_client(
args["endpoint"], args["rootCA"], args["cert"], args["key"])
# Connect.
client.connect()
signal.signal(signal.SIGINT, handler)
GPIO.setmode(GPIO.BCM)
GPIO.setup(9, GPIO.IN)
before = 0
while True:
now = GPIO.input(9)
if before == 0 and now == 1:
# Create message.
message = {"item": "01"}
# Publish.
client.publish("amzorderer", json.dumps(message), 0)
print "message published."
time.sleep(0.1)
before = now
Wir veröffentlichen eine Nachricht (Artikelklassifizierungswert "01" für den Kauf von Toilettenpapier) an AWS IoT, wenn GPIO 9 mit "RPi.GPIO" eingegeben wird.
Führen Sie das obige Skript auf Rapsberry Pi Zero aus und überprüfen Sie den Vorgang. Geben Sie den AWS IoT-Endpunkt, die Stammzertifizierungsstelle, das Clientzertifikat und den Pfad des privaten Schlüssels als Argumente für das Skript an. Obwohl dies in der README-Datei von AWS IoT SDK beschrieben ist, lautet die Stammzertifizierungsstelle hier. Erhalten von /content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem). Was ist ein Client-Zertifikat? Der private Schlüssel ist in der Zip-Datei enthalten, die beim Einrichten von AWS IoT heruntergeladen wurde.
$ python test.py -e <endpoint> -r <rootCA path> -c <certificate path> -k <private key path>
2016-12-11 08:15:31,661 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Paho MQTT Client init.
2016-12-11 08:15:31,664 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - ClientID: raspi0
2016-12-11 08:15:31,667 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Protocol: MQTTv3.1.1
2016-12-11 08:15:31,672 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Register Paho MQTT Client callbacks.
2016-12-11 08:15:31,675 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - mqttCore init.
2016-12-11 08:15:31,680 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load CAFile from: root-CA.crt
2016-12-11 08:15:31,683 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load Key from: raspi0.private.key
2016-12-11 08:15:31,687 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load Cert from: raspi0.cert.pem
2016-12-11 08:15:31,691 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for publish queueing: queueSize = 1
2016-12-11 08:15:31,696 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for publish queueing: dropBehavior = Drop Newest
2016-12-11 08:15:31,699 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Set maximum connect/disconnect timeout to be 10 second.
2016-12-11 08:15:31,704 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Set maximum MQTT operation timeout to be 5 second
2016-12-11 08:15:31,710 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Connection type: TLSv1.2 Mutual Authentication
2016-12-11 08:15:32,384 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Connected to AWS IoT.
2016-12-11 08:15:32,386 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Connect time consumption: 70.0ms.
Als ich den Taktschalter drückte, wurde eine Nachricht an AWS IoT veröffentlicht und der Kauf von "Toilettenpapier" bei Amazon erfolgreich abgeschlossen.
Miniaturisierung von Clientgeräten Dieses Mal verwendet das Netzteil einen mobilen Akku, aber ich möchte Lithiumpolymer verwenden, um die Größe zu reduzieren. Ich möchte ein kleines Bullet Board verwenden.
Unterstützt mehrere Tasten Ich hätte gerne mehrere Tasten, z. B. den Kauf von Toilettenpapier, wenn die Taste pressed gedrückt wird, und den Kauf von Saran Wrap, wenn die Taste ② gedrückt wird.
Erstellung von Schaltflächen
Recommended Posts