Share
Embed
Pythonと便利ガジェット、サービス、ツールを使ってセンシング〜見える化してみよう
【PyCon JP 2019の発表資料です】
Pythonと便利ガジェット/サービス/ツールを使って、まかせるところはまかせて、「つくらない」「やらない」をテーマに、センシング〜Webで見える化までを目指します。
Yuji Chino
September 16, 2019
Transcript
191 slides
-
͓લ୭Α ༤ೋ facebook : chinoppy twitter : @chinoppy0727 (ג)ຊγεςϜٕݚʢJSLʣ
ॴଐ ݝࢢʹ͋Γ·͢ ࠓͷPyCon JP 2019 ͰʮGold Sponsorʯ WebΤϯδχΞʢPythonͬͯ·͢ʂʣ ۀͱϓϥΠϕʔτͰIoTͯ͠·͢ GEEKLAB.NAGANOͷཧਓ ͕ࣾӡӦ͢ΔίϛϡχςΟεϖʔε ௨শɿ͗ʔΒ΅ ฏ9:00ʙ18:00͜Ζ·Ͱແྉ։์͍ͯ͠·͢ ࡞ۀͱͯ͠ར༻Ͱ͖·͢ͷͰɺ͓ؾܰʹ͓ӽ͍ͩ͘͠͞ -
εϥΠυɺίʔυʹ͍ͭͯ ͜ͷεϥΠυެ։͠·͢ʂ εϥΠυதͷίʔυ࠷খݶͷهࡌͱͳͬͯ·͢ GithubͰެ։தͰ͢ʢҰ෦ඇެ։ίʔυ͋Γʣ ηϯγϯάʢRaspberry PiΛલఏʣ https://github.com/peacemaker07/iot_making_for_raspberry_pi Ϋϥυʢserverless frameworkʣ https://github.com/peacemaker07/iot_making_for_sls
WebʢDjangoʣ https://github.com/peacemaker07/iot_making_for_django ※ࠓޙਵ࣌ɺߋ৽༧ఆͰ͢ -
ߏɿσόΠε Raspberry Pi 3 Model B Grove System Թ࣪ܭ Իηϯα
ϕʔεϢχοτɿGrove Pi ωοτϫʔΫ ໌Δ͞ ਫηϯα Χϝϥ AWS IoT Core -
ߏɿΫϥυ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
Amazon API Gateway Amazon Simple Storage Service -
ߏɿWeb AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service ΫϥυଆͰઆ໌ࡁΈ Auth0 -
લ σόΠε ηϯγϯάσʔλͷऔಘ ωοτϫʔΫ Ϋϥυૹ৴ MQTT Raspberry Pi㱺AWS IoT Core
Raspberry Pi㱺SORACOM㱺AWS IoT Core Ϋϥυ SORACOM㱺AWS IoT Core AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘ -
ߏ Raspberry Pi 3 Model B Grove System Թ࣪ܭ Իηϯα
ϕʔεϢχοτɿGrove Pi ωοτϫʔΫ ໌Δ͞ ਫηϯα Χϝϥ AWS IoT Core -
લ σόΠε ηϯγϯάσʔλͷऔಘ ωοτϫʔΫ Ϋϥυૹ৴ MQTT Raspberry Pi㱺AWS IoT Core
Raspberry Pi㱺SORACOM㱺AWS IoT Core Ϋϥυ SORACOM㱺AWS IoT Core AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘ -
ηϯαɺRaspberry Pi Raspberry Pi 3 Model B Grove System Թ࣪ܭ
Իηϯα ϕʔεϢχοτɿGrove Pi ωοτϫʔΫ ໌Δ͞ ਫηϯα Χϝϥ AWS IoT Core -
ηϯαʔ Grove System seeed studio͕ࣾ։ൃ https://www.seeedstudio.com ϕʔεϢχοτͱඪ४Խ͞ΕͨίωΫλΛඋ͍͑ͯΔ ૠ͚ͩ͢Ͱѻ͑ΔηϯαʔͳͲͷϞδϡʔϧ͕ଟ PythonϥΠϒϥϦ͕͋Δʂ https://github.com/DexterInd/GrovePi/tree/master/Software/Python
ࢀߟ : http://wiki.seeedstudio.com/Grove_System/ Μ͚ͩͮɺઢͷඞཁ͕ͳ͘PythonϥΠϒϥϦ͋Δ -
ηϯαʔ ૠ͚ͩ͢ͰηοτΞοϓྃʂ Interface Digital Grove Analog Grove UART Grove I2C
Sensor Թ࣪ ໌Δ͞ ਫ Ի LED Ϙλϯ LCD 100छྨҎ্͋Δ -
ϚΠίϯʗίϯϐϡʔλ Raspberry Pi γϯάϧϘʔυίϯϐϡʔλ ͱͱڭҭΛఆ੍ͯ͠࡞ ༻Ϟσϧɿ3 Model B 3͔ΒແઢLANࡌ 3͔ΒBluetoothඪ४ࡌ
͜Εʹͱͳ͍UART௨৴ҙ ࢀߟɿPi 3 serial Issues https://www.raspberrypi.org/forums/ viewtopic.php? f=63&t=151454#p993901 OS Raspbian https://www.raspberrypi.org/downloads/ raspbian/ Stretch Lite -
σδλϧ >>> import grovepi >>> >>> sensor = 4 #
The Sensor goes on digital port 4. >>> blue = 0 # The Blue colored sensor. >>> white = 1 # The White colored sensor. >>> >>> grovepi.dht(sensor, white) [32.4, 44.0] # Թ, ࣪ >>> Թ࣪Λऔಘ http://wiki.seeedstudio.com/Grove-TemperatureAndHumidity_Sensor/ ʲblue : Temperature&Humidity Sensorʳ ϚΠφεͷԹ͕ଌΕͳ͍ ͍͚҆Ͳਫ਼ѱ͍ 820ԁ ʲwhite : Temperature&Humidity Sensor proʳ ϚΠφεͷԹ͕ଌΕΔ blueΑΓߴ͍͕ਫ਼͕Α͍ 2,095ԁ -
I2C $ $ cd [yourpath]/GrovePi/Software/Python/grove_i2c_digital_light_sensor $ pwd [yourpath]/GrovePi/Software/Python/grove_i2c_digital_light_sensor # αϯϓϧιʔεॆ࣮
$ python grove_i2c_digital_light_sensor.py Lux: 72 [Vis+IR=570, IR=276 @ Gain=1x, Timing=402.0ms] Lux: 72 [Vis+IR=570, IR=276 @ Gain=1x, Timing=402.0ms] ɾɾɾ ໌Δ͞Λऔಘ http://wiki.seeedstudio.com/Grove-Digital_Light_Sensor/ Digital Light Sensor -
Ξφϩά >>> import grovepi >>> >>> loudness_sensor = 0 >>>
grovepi.analogRead(loudness_sensor) 124 >>> Իηϯα http://wiki.seeedstudio.com/Grove-Loudness_Sensor/ Loudness Sensor -
Χϝϥ >>> from picamera import PiCamera >>> >>> camera =
PiCamera() >>> >>> camera.start_preview() <picamera.renderers.PiPreviewRenderer object at 0x769d16b0> >>> >>> # ࡱӨ >>> camera.capture('./sample.jpg') >>> >>> camera.stop_preview() >>> camera.close() ࡱӨ 3BTQCFSSZ1J$BNFSB.PEVMF7ΧϝϥϞδϡʔϧ -
ηϯαͷσʔλऔಘྃʂ Raspberry Pi 3 Model B Grove System Թ࣪ܭ Իηϯα
ϕʔεϢχοτɿGrove Pi ωοτϫʔΫ ໌Δ͞ ਫηϯα Χϝϥ AWS IoT Core આ໌ࡁΈ -
લ σόΠε ηϯγϯάσʔλͷऔಘ ωοτϫʔΫ Ϋϥυૹ৴ MQTT Raspberry Pi㱺AWS IoT Core
Raspberry Pi㱺SORACOM㱺AWS IoT Core Ϋϥυ SORACOM㱺AWS IoT Core AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘ -
ωοτϫʔΫɺΫϥυૹ৴ Raspberry Pi 3 Model B Grove System Թ࣪ܭ Իηϯα
ϕʔεϢχοτɿGrove Pi ωοτϫʔΫ ໌Δ͞ ਫηϯα Χϝϥ AWS IoT Core આ໌ࡁΈ -
SORACOM IoT ϓϥοτϑΥʔϜ MVNO ͱͯ͠σʔλ௨৴ SIM Λఏڙ ϞόΠϧ௨৴ͱΫϥυΛҰ؏ͯ͠ఏڙ ࢀߟɿ https://soracom.jp/overview/
ωοτϫʔΫ ωοτϫʔΫɺηΩϡϦςΟΛ͓·͔ͤʂ -
Ϋϥυૹ৴ Raspberry Pi 㱺 AWS IoT Core Raspberry Pi 㱺
SORACOM 㱺 AWS IoT Core AWS IoT Core AWS IoT Core -
MQTT Message Queuing Telemetry Transportͷུ Pub/Subܕσʔλ৴Ϟσϧ ඇྗͳσόΠεωοτϫʔΫ͕ෆ҆ఆͳॴͰಈ࡞͢͠ ͍Α͏ʹϝοηʔδిจ͕ܰྔʹઃܭ͞Ε͍ͯΔ ࢀߟɿΟΩϖσΟΞʮMQ Telemetry
Transportʯ ɹɹɿhttps://tech-blog.optim.co.jp/entry/2019/08/20/163000 -
MQTT ϒϩʔΧʔ ʢதܧऀʣ MQTT ΫϥΠΞϯτA ΫϥΠΞϯτB ΞΫλʔ ύϒϦογϟʔʢൃߦऀʣ αϒεΫϥΠόʔʢߪಡऀʣ ϒϩʔΧʔʢதܧऀʣ
ϝοηʔδͷૹ ϝοηʔδΛൃߦʢૹ৴ʣ͢ΔɿPublish ϝοηʔδͷߪಡʢड৴ʣΛొ͢ΔɿSubscribe ϝοηʔδͷΩʔɿtopic -
MQTT ϒϩʔΧʔ ʢதܧऀʣ σʔλΛड͚औΓɺ ֘͢Δߪಡऀ σʔλΛૹ MQTT ΫϥΠΞϯτA ΫϥΠΞϯτB ΫϥΠΞϯτʮϒϩʔΧʔʯΛ௨ͯ͠ɺϝοηʔδͷΓͱΓΛ͢Δ
ϒϩʔΧʔɺΫϥΠΞϯτ͔Βૹ৴͞ΕͨσʔλΛ ͦͷtopicΛαϒεΫϥΠϒ͍ͯ͠ΔΫϥΠΞϯτૹΔ ʲPublishʳ topicɿenvironment/ ʲSubscribeʳ topicɿenvironment/ ΫϥΠΞϯτC ʲSubscribeʳ topicɿenvironment/ ΫϥΠΞϯτD -
MQTT ϒϩʔΧʔ ʢதܧऀʣ σʔλΛड͚औΓɺ ֘͢Δߪಡऀ σʔλΛૹ MQTT ΫϥΠΞϯτA ΫϥΠΞϯτB ʲPublishʳ
topicɿenvironment/ ʲSubscribeʳ topicɿenvironment/ ΫϥΠΞϯτC ʲSubscribeʳ topicɿenvironment/ ϒϩʔΧʔ͋ΔఔɺPublish͞ΕͨϝοηʔδΛอ࣋Ͱ͖Δ ΫϥΠΞϯτD ʲSubscribeʳ topicɿenvironment/ -
Ϋϥυૹ৴ Raspberry Pi 㱺 AWS IoT Core Raspberry Pi 㱺
SORACOM 㱺 AWS IoT Core AWS IoT Core AWS IoT Core MQTTS MQTT -
Ϋϥυૹ৴ Raspberry Pi 㱺 AWS IoT Core ४උ AWS IoT
ͷSDKͷΠϯετʔϧ https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sdks.html#iot-python-sdk σόΠεূ໌ॻΛσόΠεଆʹஔ SDK σόΠεূ໌ॻ AWS IoT Core MQTTS -
Ϋϥυૹ৴ Raspberry Pi 㱺 AWS IoT Core αϯϓϧίʔυ͔Βൈਮ https://github.com/aws/aws-iot-device-sdk-python/blob/master/samples/basicPubSub/basicPubSub.py ɾɾɾʢলུʣ
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient ɾɾɾʢলུʣ # Read in command-line parameters parser = argparse.ArgumentParser() parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your AWS IoT custom endpoint") ɾɾɾʢলུʣ # Init AWSIoTMQTTClient myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId) myAWSIoTMQTTClient.configureEndpoint(host, port) myAWSIoTMQTTClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath) ɾɾɾʢলུʣ # AWSIoTMQTTClient connection configuration myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing ɾɾɾʢ࣍ͷϖʔδʣ ᶃ ূ໌ॻͷಡΈࠐΈ ᶄΫϥΠΞϯτͷॳظԽ ᶅଓͷઃఆ -
Ϋϥυૹ৴ Raspberry Pi 㱺 AWS IoT Core αϯϓϧίʔυ͔Βൈਮ https://github.com/aws/aws-iot-device-sdk-python/blob/master/samples/basicPubSub/basicPubSub.py ɾɾɾʢଓ͖ʣ
# Connect and subscribe to AWS IoT myAWSIoTMQTTClient.connect() ɾɾɾʢলུʣ # Publish to the same topic in a loop forever message = {} message['message'] = args.message messageJson = json.dumps(message) # Connect and subscribe to AWS IoT myAWSIoTMQTTClient.publish(topic, messageJson, 1) ɾɾɾʢলུʣ ᶆAWS IoT Coreଓ ᶇૹ৴σʔλ४උ ᶈpublishʂʂʂ -
Ϋϥυૹ৴ Raspberry Pi 㱺 AWS IoT Core Raspberry Pi㱺 SORACOM
㱺 AWS IoT Core AWS IoT Core AWS IoT Core MQTTS MQTT આ໌ࡁΈ -
Ϋϥυૹ৴ Raspberry Pi 㱺 SORACOM 㱺 AWS IoT Core σόΠεଆͰઆ໌
ΫϥυଆͰઆ໌ MQTT AWS IoT Core -
Ϋϥυૹ৴ Raspberry Pi 㱺 SORACOM ४උ PythonͷMQTTϥΠϒϥϦͷΠϯετʔϧ Paho-mqttΛ༻ https://pypi.org/project/paho-mqtt/ SORACOM
Air SIM ࠓճηϧϥʔΛ༻ USBυϯάϧ ͜ͷதʹSIMΛ͍ΕͯRaspberry Piʹૠ͢ʂ ※υϯάϧͷઃఆʹؔͯ͠Githubࢀর MQTT -
Ϋϥυૹ৴ Raspberry Pi 㱺 SORACOM σόΠεূ໌ॻ SDK ɺAWSૹ৴͢Δͱ͖ͱͷҧ͍ σόΠεূ໌ॻΛஔ͘ඞཁ͕ͳ͍ SDKෆཁ
Ϋϥυʹґଘ͠ͳ͍ίʔυ͕ॻ͚Δ MQTT -
Ϋϥυૹ৴ import json import time import paho.mqtt.client as mqtt host
= 'beam.soracom.io' port = 1883 topic = 'environment' # ॳظԽ client = mqtt.Client(protocol=mqtt.MQTTv311) client.connect(host, port=port, keepalive=60) time.sleep(5) # ૹ৴σʔλ json_dict = { 'temp': 34, 'humi': 45, } # ηϯγϯάใΛૹ৴ result = client.publish(topic, json.dumps(json_dict), qos=1) client.disconnect() Raspberry Pi 㱺 SORACOM ᶃ ΫϥΠΞϯτॳظԽ ᶄSORACOMଓ ᶅૹ৴σʔλ४උ ᶆpublishʂʂʂ -
Ϋϥυૹ৴ྃʂ Raspberry Pi 㱺 AWS IoT Core Raspberry Pi 㱺
SORACOM 㱺 AWS IoT Core AWS IoT Core AWS IoT Core MQTTS MQTT આ໌ࡁΈ -
ηϯα͔ΒͷσʔλऔಘɺωοτϫʔΫ Ϋϥυͷૹ৴ྃʂ Raspberry Pi 3 Model B Grove System Թ࣪ܭ
Իηϯα ϕʔεϢχοτɿGrove Pi ωοτϫʔΫ ໌Δ͞ ਫηϯα Χϝϥ AWS IoT Core આ໌ࡁΈ -
ߏ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
Amazon API Gateway Amazon Simple Storage Service -
લ σόΠε ηϯγϯάσʔλͷऔಘ ωοτϫʔΫ Ϋϥυૹ৴ MQTT Raspberry Pi㱺AWS IoT Core
Raspberry Pi㱺SORACOM㱺AWS IoT Core Ϋϥυ SORACOM㱺AWS IoT Core AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘ -
SORACOM 㱺 AWS IoT Core AWS IoT Core AWS Lambda
Amazon DynamoDB AWS Lambda Amazon API Gateway Amazon Simple Storage Service -
SORACOMͷαʔϏεͰసૹ SORACOM 㱺 AWS IoT Core Beam ҉߸Խͯ͠ σʔλΛసૹͯ͘͠ΕΔ ূ໌ॻSORACOM
ొͯ͠ઃఆ࣌ʹࢦఆ͢Δ AWS IoT Core Funnel σʔλΛಛఆͷΫϥυαʔϏεసૹ͢ΔαʔϏε MQTT MQTTS -
SORACOM㱺AWS IoT Coreૹ৴ྃʂ AWS IoT Core AWS Lambda Amazon DynamoDB
AWS Lambda Amazon API Gateway Amazon Simple Storage Service આ໌ࡁΈ -
AWS IoT Core ͔ΒAmazon DynamoDBʹσʔλอଘ AWS IoT Core AWS Lambda
Amazon DynamoDB AWS Lambda Amazon API Gateway Amazon Simple Storage Service આ໌ࡁΈ -
AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘ AWS IoT Core AWS Lambda Amazon
DynamoDB AWS Lambda IoT rule ಛఆͷtopicΛड৴ͨ͠Βޙड़ ͷactionΛ࣮ߦ IoT action DynamoDBͷςʔϒϧσʔλ Λొ LambdaΛ࣮ߦ ͳͲෳͷΞΫγϣϯΛα ϙʔτ͍ͯ͠Δ ࢀߟɿAWS IoT ϧʔϧΞΫγϣϯ https://docs.aws.amazon.com/ ja_jp/iot/latest/developerguide/ iot-rule-actions.html IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service -
AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘ σόΠε͔ΒૹΒΕ͖ͯͨσʔλ { “imsi": XXXX, “timestamp": 1565276403000,
“air_quality”: 83, “humi": 41.8, “loudness": 88, “lux": 35, “temp": 25.3, } IoT action IoT rule -
AWS IoT Core͔ΒAmazon DynamoDBʹσʔλอଘྃ AWS IoT Core AWS Lambda Amazon
DynamoDB AWS Lambda Amazon API Gateway Amazon Simple Storage Service IoT action IoT rule આ໌ࡁΈ આ໌ࡁΈ -
ՃใɿSigfoxʢγάϑΥοΫεʣ ࠃSigfox͕ࣾఏڙ͢ΔLPWAωοτϫʔΫ LPWAʹLow Power Wide Area Ձ֨ɾফඅిྗɾڑૹ͕ಛ ηϯαʔ ੍ݶ 1ճͷ࠷େૹ৴ྔ12όΠτ
1Ͱૹ৴Ͱ͖Δճʢ্Γ140ճ/˞ɺԼΓ4ճ/ʣ ※10ʹ1ճϖʔε -
͍Ζ͍ΖͳαʔϏεΛ͍·͢ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
AWS Identity and Access Management Permisions Role Amazon API Gateway Amazon Simple Storage Service -
serverless framework https://serverless.com/framework/ Node.jsΛར༻ͨ͠serverlessΛߏஙɺཧɺσϓϩΠΛͰ͖Δπʔ ϧ yamlʹߏங༰Λهࡌ͢ΕίϚϯυҰൃͰσϓϩΠ AWSɺGCPɺAzureͳͲʹରԠ AWS Lambda PythonͷϥΠϒϥϦҰॹʹzipԽͯ͠σϓϩΠ
docker-lambdaΠϝʔδΛͬͯ ίϯύΠϧޙʹσϓϩΠͯ͘͠ΕΔ ߏཧπʔϧ ྨࣅαʔϏε AWS SAM https://aws.amazon.com/jp/serverless/sam/ serverless ༻ʹCloudFormationΛ֦ுͨ͠AWSαʔϏε AWSͷΈ༻Ͱ͋Εɺͪ͜Βݕ౼ͯ͠Έ͍ͯͩ͘͞ -
ઃఆใͷอ࣋ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
Amazon API Gateway Amazon Simple Storage Service આ໌ࡁΈ આ໌ࡁΈ -
ઃఆใͷอ࣋ Device ShadowαʔϏε https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-device-shadows.html AWS IoT CoreͱσόΠεؒΛJSONͰΓͱΓʢGET/UPDATEʣ͕Ͱ͖Δ ͜ͷJSONʹσόΠεͷʮઃఆใʯʮঢ়ଶʯΛ͓ͬͯ͘ Device ShadowαʔϏε
{ # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } -
ઃఆใͷอ࣋ Device ShadowαʔϏε ηΫγϣϯ desiredɿΫϥυ͔Βͷཁٻ reportedɿσόΠεͷঢ়ଶ deltaɿΫϥυͱσόΠεͷࠩ Device ShadowαʔϏε {
# Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } -
σόΠεଆ cronͰຖਖ਼࣌ɺ5͝ͱىಈ ىಈ͝ͱDevice ShadowΛࢀর Device Shadow ૹ৴ִؒʢintervalʣ 5㱺10ִؒʹมߋ Device ShadowαʔϏε
{ # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 # 10ִؒ } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } ԹΛຖਖ਼࣌ɺΫϥυૹΔ -
AWS IoT Core ԹΛຖਖ਼࣌ɺΫϥυૹΔ Device Shadowͷऔಘ Ϋϥυ σόΠε GETཁٻ Device
ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } -
AWS IoT Core Ϋϥυ σόΠε JSONΛड͚औΔ GETཁٻ Device ShadowαʔϏε {
# Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } ԹΛຖਖ਼࣌ɺΫϥυૹΔ Device Shadowͷऔಘ -
AWS IoT Core ԹΛૹ৴ Ϋϥυ σόΠε JSONΛड͚औΔ GETཁٻ Device ShadowαʔϏε
{ # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } ݱࡏ࣌ࠁ 11 : 40 㱺ԹΛૹ৴ ԹΛຖਖ਼࣌ɺΫϥυૹΔ -
AWS IoT Core Device Shadow ߋ৽ Ϋϥυ σόΠε JSONΛड͚औΔ GETཁٻ
Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } ݱࡏ࣌ࠁ 11 : 40 㱺ԹΛૹ৴ UPDATEཁٻ ૹ৴σʔλ { "reported": { "sensor": { "interval": 10 } }, } ԹΛຖਖ਼࣌ɺΫϥυૹΔ -
AWS IoT Core Ϋϥυ σόΠε JSONΛड͚औΔ GETཁٻ Device ShadowαʔϏε {
# Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 } }, # ΫϥυͱσόΠεͷࠩ # ͕ͳ͘ͳΔʂ } Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ "delta": { "sensor": { "interval": 10 } } } ݱࡏ࣌ࠁ 11 : 40 㱺ԹΛૹ৴ UPDATEཁٻ ૹ৴σʔλ { "reported": { "sensor": { "interval": 10 } }, } ԹΛຖਖ਼࣌ɺΫϥυૹΔ Device Shadow ߋ৽ -
AWS IoT Core Ϋϥυ σόΠε GETཁٻ Device ShadowαʔϏε { #
Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ # ͕ͳ͘ͳΔʂ } ԹΛຖਖ਼࣌ɺΫϥυૹΔ Device Shadow औಘ MQTT ͰΓͱΓ͍ͯ͠Δ -
AWS IoT Core Ϋϥυ σόΠε JSONΛड͚औΔ Device ShadowαʔϏε { #
Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 5 } }, # ΫϥυͱσόΠεͷࠩ # ͕ͳ͘ͳΔʂ } ԹΛຖਖ਼࣌ɺΫϥυૹΔ Device Shadow औಘ Subscribe GETཁٻʢPublishʣ MQTT ͰΓͱΓ͍ͯ͠Δ -
ઃఆใͷอ࣋ subscribe import paho.mqtt.client as mqtt ɾɾɾ def on_connect(client, userdata,
flags, respons_code): # ϒϩʔΧʔʹଓͰ͖ͨΒαϒεΫϥΠϒ client.subscribe(topic) def on_message(client, userdata, msg): # ϝοηʔδड৴ʢDevice Shadow͔Βͷσʔλड৴ʣ࣌ json_str = msg.payload.decode(encoding='utf-8') client.disconnect() client = mqtt.Client(protocol=mqtt.MQTTv311) # callbackΛొ client.on_connect = on_connect client.on_message = on_message # ଓ client.connect(host, port=port, keepalive=60) # ͪड͚ঢ়ଶʹ͢Δ client.loop_forever() Device Shadow ͔Βड৴ͨ͠σʔλ 㱺͜ΕΛ͍͍ͨʂ on_messageΛcallback ొ͢Δ ※ຊίʔυpaho-mqtt༻࣌ͷྫ ※AWS IoT SDK༻࣌SDKͷϝιουΛ༻ͯ͠Device ShadowͱΓͱΓ͠·͢ -
ઃఆใͷอ࣋ subscribe import paho.mqtt.client as mqtt ɾɾɾ @app.task def run_subscribe(host,
port, topic): redis_client = RedisClient() def on_connect(client, userdata, flags, respons_code): client.subscribe(topic) def on_message(client, userdata, msg): json_str = msg.payload.decode(encoding='utf-8') redis_client.set('token', json_str) client.disconnect() redis_client.delete('token') client = mqtt.Client(protocol=mqtt.MQTTv311) client.on_connect = on_connect client.on_message = on_message client.connect(host, port=port, keepalive=60) # ͪड͚ঢ়ଶʹ͢Δ client.loop_forever() Device Shadow ͔Βड৴ͨ͠σʔλ 㱺Redisʹset PythonͷඇಉظϥΠϒϥϦ CeleryΛ༻ͯ͠λεΫԽ ※ຊίʔυpaho-mqtt༻࣌ͷྫ ※AWS IoT SDK༻࣌SDKͷϝιουΛ༻ͯ͠Device ShadowͱΓͱΓ͠·͢ -
ઃఆใͷอ࣋ subscribe + publishʢGETཁٻʣ import paho.mqtt.client as mqtt ɾɾɾ redis_client
= RedisClient() # αϒεΫϥΠϒͷඇಉظλεΫ࣮ߦ result_sub = tasks_mqtt.run_subscribe.delay(ɾɾɾ) # publishʢGETཁٻʣ client = mqtt.Client(protocol=mqtt.MQTTv311) client.connect(host, port=port, keepalive=60) result = client.publish(topic, json.dumps(json_dict), qos=1) # αϒεΫϥΠϒͷඇಉظλεΫऴྃͪ while not result_sub.ready(): time.sleep(1) # Device ShadowΛऔಘ value = redis_client.get('token') payload_str = value.decode(encoding='utf-8') # ԹΛpublish # Device ShadowΛߋ৽ʢupdateͷτϐοΫʹpublishʣ Redis͔ΒDevice Shadow ͷσʔλΛऔಘ subscribeͷλεΫΛ࣮ߦ publishʂʂʂ ※ຊίʔυpaho-mqtt༻࣌ͷྫ ※AWS IoT SDK༻࣌SDKͷϝιουΛ༻ͯ͠Device ShadowͱΓͱΓ͠·͢ αϒεΫϥΠϒͷ λεΫऴྃͪ -
ঢ়ଶͷมߋ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
Amazon API Gateway Amazon Simple Storage Service આ໌ࡁΈ આ໌ࡁΈ ৄࡉ Appendixࢀর -
ࢹ AWS IoT Core AWS Lambda Amazon DynamoDB Amazon Simple
Storage Service AWS Lambda Amazon API Gateway આ໌ࡁΈ આ໌ࡁΈ -
AWS IoT Core ࢹ ࣸਅΛࡱͬͯTwitterߘ͢Δ Ϋϥυ σόΠε ը૾Λૹ৴ Amazon Simple
Storage Service TriggerͰ LambdaΛىಈ ࡱӨ -
AWS IoT Core ࢹ ࣸਅΛࡱͬͯTwitterߘ͢Δ Ϋϥυ σόΠε ը૾Λૹ৴ Amazon Simple
Storage Service TriggerͰ LambdaΛىಈ ࡱӨ ͲͷΑ͏ʹ Tweet͍ͯ͠Δ͔ -
ࢹ ࣸਅΛࡱͬͯTwitterߘ͢Δ url_media = "https://upload.twitter.com/1.1/media/upload.json" url_text = "https://api.twitter.com/1.1/statuses/update.json" CK =
os.getenv('TWITTER_CONSUMER_KEY') ɾɾɾʢলུʣ twitter = OAuth1Session(CK, CS, AT, ATS) # S3อଘ͞Εͨը૾Λऔಘ bucket_name = event['Records'][0]['s3']['bucket']['name'] object_key = event['Records'][0]['s3']['object']['key'] response = s3.get_object(Bucket=bucket_name, Key=object_key) body = response['Body'].read() # ը૾Λpost files = {"media": body} req_media = twitter.post(url_media, files=files) media_id = json.loads(req_media.text)['media_id'] # tweet jst = timezone(timedelta(hours=+9), 'JST') now = datetime.now(jst) params = {"status": "{} XXXXXX ษڧձ։࠵த ษڧத #glnagano" .format(now.strftime(“%Y/%m/%d %H:%M")), "media_ids": [media_id]} req_text = twitter.post(url_text, params=params) ը૾Λऔಘ Twitterը૾Λpost TwitterTweet -
ࢹ·ͱΊ ࣸਅΛࡱͬͯTwitterߘ͢Δ Twitterͷૹ৴ɺʮγʔΫϨοτΩʔʯʮτʔΫϯʯͳͲ͕ඞཁ ΫϥυଆͰTweet͢ΔͷͰΫϥυଆͰΩʔ͕ཧͰ͖Δ ҙ AWS IoT CoreͰΓͱΓͰ͖Δσʔλྔ128KB·Ͱ https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html#iot-protocol-limits ࡱӨ࣌ʹը૾ղ૾Λམͱ͢
Ұ࣌తͳτʔΫϯΛAWS IoTܦ༝Ͱऔಘ͠ɺ σόΠε͔ΒS3ΞοϓϩʔυͳͲ ϥʔδσʔλΞοϓϩʔυύλʔϯ https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-iot#37 -
௨ AWS IoT Core AWS Lambda Amazon DynamoDB Amazon Simple
Storage Service AWS Lambda Amazon API Gateway આ໌ࡁΈ આ໌ࡁΈ આ໌ࡁΈ આ໌ࡁΈ LINE Notifyͷઆ໌ Appendixࢀর -
AWS IoT Core ௨ Թ͕ᮢҎ্ʹͳͬͨΒ௨͢Δ Ϋϥυ σόΠε ԹΛૹ৴ LambdaΛ࣮ߦ ᮢΛνΣοΫͯ͠
֤αʔϏε௨ ͲͷΑ͏ʹ ૹ৴͍ͯ͠Δ͔ -
import ssl import slackweb class Slack: slack_webhook_url = '[slackͰऔಘͨ͠webhookͷURL]' @staticmethod
def notify(slack_url, message): ssl._create_default_https_context = ssl._create_unverified_context slack = slackweb.Slack(url=slack_url) slack.notify(text=message, username="notify", icon_emoji=":bell:") # slack௨ Slack.notify(Slack.slack_webhook_url, 'Թ͕30Ҏ্Ͱ͢ʂ') ௨ Թ͕ᮢҎ্ʹͳͬͨΒ௨͢Δ Slack௨ʂ -
import requests class LineNotify: @classmethod def notify(cls, message): payload =
{'message': message} res = cls._requests(payload) return res @classmethod def _requests(cls, payload): url = 'https://notify-api.line.me/api/notify' access_token = '[ΞΫηετʔΫϯ]' headers = {'authorization': 'Bearer {}'.format(access_token)} res = requests.post(url, headers=headers, params=payload) return res # LINE Notifyʹ௨ LineNotify.notify('Թ͕30Ҏ্Ͱ͢ʂ') ௨ Թ͕ᮢҎ্ʹͳͬͨΒ௨͢Δ LINE Notifyʹ௨ʂ -
σʔλอଘɺࢹɺ௨͕Ͱ͖·ͨ͠ʂ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
Amazon API Gateway Amazon Simple Storage Service આ໌ࡁΈ -
ߏ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service ΫϥυଆͰઆ໌ࡁΈ Auth0 -
APIͰηϯαͷσʔλΛެ։ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service ΫϥυଆͰઆ໌ࡁΈ Auth0 ΦʔιϥΠβʔɾ Auth0ͷৄࡉ Appendixࢀর -
ΞΫηε੍ݶ ࠓճAmazon API Gateway + AWS LambdaͰσʔλΛެ։ Amazon API GatewayͷΞΫηε੍ݶ
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway- control-access-to-api.html ࠓճʮAPI Gateway Lambda ΦʔιϥΠβʔʯΛ༻ https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/ apigateway-use-lambda-authorizer.html τʔΫϯͷੜɺೝূAuth0Λ༻ -
ΞΫηε੍ݶ Auth0Λར༻ Amazon API Gateway Auth0 ϦΫΤετલʹ τʔΫϯऔಘ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ
ϦΫΤετͷ τʔΫϯΛೝূ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ -
APIͰηϯαͷσʔλΛެ։·Ͱྃʂ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service ΫϥυଆͰઆ໌ࡁΈ Auth0 આ໌ࡁΈ -
Webϖʔδ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service ΫϥυଆͰઆ໌ࡁΈ Auth0 આ໌ࡁΈ -
Char.js άϥϑදࣔ const chartDht = new Chart(ctxDht, { type: 'line',
data: { labels: labels, datasets: [ { label: 'Թ', data: dataTemp, backgroundColor: 'rgba(0, 0, 0, 0)', borderColor: 'rgba(255, 99, 132, 1)', borderWidth: 1 }, { label: '࣪', data: dataHumi, ɾɾɾ }, { label: 'ۭؾͷ࣭', data: dataAirQuality, ɾɾɾ },] }, options: { ɾɾɾ } }); -
ɾɾɾ columnDefs: [ // ૹ৴࣌ { "targets": 0, data: "send_time"},
// Թ { "targets": 1, data: "temp", "render": function (data, type, full, meta) { return (webCommons.dispRange(data)) ? data : "-"; } }, // ࣪ { "targets": 2, data: "humi", ɾɾɾ { className: "center", "targets": [ 0, 1, 2, 3, 4, 5, ] } ], ɾɾɾ ςʔϒϧදࣔ DataTables -
WebϖʔδͰݟ͑ΔԽ·Ͱྃʂ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
IoT action IoT rule Amazon API Gateway Amazon Simple Storage Service ΫϥυଆͰઆ໌ࡁΈ Auth0 આ໌ࡁΈ આ໌ࡁΈ -
ॳظίετ ໊ ݸ ߹ܭ ࢀߟݩ 3BTQCFSSZ1J .PEFM# ԁ
੫ࠐ ,4: (SPWF1J ԁ ੫ࠐ "NB[PO Թ࣪ܭQSP ԁ ੫ࠐ "NB[PO (64#υϯάϧ ", ԁ ੫ൈ 403"$0. 403"$0.4*. ԁ ੫ൈ ˞QMBO%ɺσʔλ௨৴ͷΈ ߹ܭ ԁ ॳظඅ༻ʢૹྉผʣ ※ηϯαͯ͢ܝࡌ͍ͯ͠·ͤΜ -
ϥϯχϯάίετ ༻్ ͝ͱ ݄͝ͱ උߟ ηϯγϯάσʔλͷૹ৴ ճʢ͝ͱʣ࣌✕✕ ܭɿճ ճ✕ ܭɿճ
σόΠε㱺 "84*P5$PSF㱺 ֤αʔϏε σʔλόοΫΞοϓ ճ ճ %ZOBNP%#ͷͷσʔ λΛ4ʹόοΫΞοϓ ௨ ఆظ͕ճ ෆఆظ͕ճ͘Β͍ ܭɿճ ճ✕ ܭɿճ TMBDLɺ-*/&/PUJGZ ௨ 8FCϖʔδͷࢀর ճ ճ✕ ճ ※ෆఆظͰಈ͍͍ͯΔͱ͜Ζ͋ΔͨΊɺྉ࣮ۚͷ༻ྔͱҰக͠·ͤΜ ༻ස ʲσʔλͷݟ͑ΔԽʗ௨ʳ -
ϥϯχϯάίετ ༻్ ͝ͱ ݄͝ͱ උߟ ࣸਅࡱӨͨ͠5XFFU ճ ͝ͱ ࣌✕ ܭɿճ
ճ✕ ܭɿճ σόΠε㱺 "84*P5$PSF㱺 ֤αʔϏε ,ຕ✕ճ ͝ͱ ࣌✕ ܭɿ.# .#✕ ܭɿ.# ʏ %FWJDF4IBEPX ʢ(&561%"5&ʣ ճ ͝ͱ ࣌✕ ܭɿճ ճ✕ ܭɿ ճ σόΠε㱻"84*P5$PSF ※ෆఆظͰಈ͍͍ͯΔͱ͜Ζ͋ΔͨΊɺྉ࣮ۚͷ༻ྔͱҰக͠·ͤΜ ※தͷΈՔಇʢ҉͘ͳΔͱࡱӨ͠ͳ͍ʣ ༻ස ʲࢹʳ -
ϥϯχϯάίετ αʔϏε ྉۚʢ੫ผʣ උߟ "JS4*. جຊྉۚ ຕɿԁ ˞ ௨৴ྉ ԁ.#
˞ #FBN جຊྉۚ ແྉ ϦΫΤετྉ ԁϦΫΤετ ˞ ແྉར༻͋Γ SORACOM ※ಛఆҬ͚ IoT SIMɺplan-Dɺ༻։࢝ޙɺσʔλ௨৴ͷΈɺs1.standard ɹhttps://soracom.jp/services/air/cellular/price_specific_area_sim/#plan-d 1SIM 300ԁ/݄ ✕ ༻ຕ ʲσʔλͷݟ͑ΔԽʗ௨ɺࢹʳ -
ϥϯχϯάίετ αʔϏε ༻ྉ ༻ྔ ྉۚମܥ උߟ "84*P5$PSF .FTTBHFT
ϝοηʔδԯ݅·Ͱ 64% ϝοηʔδສ݅͋ͨΓ ˞ ଞͷྉۚԁͷͨΊׂѪ %ZOBNP%# 3FBE 8SJUF (#.P DBQBDJUZVOJUɿͳͷͰແྉ (#ҎͳͷͰແྉ ˞ -BNCEB TFDPOET 3FRVFTUT ྆ํͱແྉ ˞ "NB[PO"1* (BUFXBZ 3FRVFTU ʲ"1*ίʔϧʳ ࠷ॳͷԯ ສ·Ͱ ສ͋ͨΓ64% ˞ "NB[PO4JNQMF 4UPSBHF4FSWJDF 3FRVFTUT 3FRVFTUT (#.P 165ଞ·Ͱɿ (&5ଞ·Ͱɿ ࠷ॳͷ5#݄·Ͱɿ(# ˞ ߹ܭ AWS ※౦ژϦʔδϣϯͷྉۚͰ͢ ※ྉۚମܥলུͯ͠Δͱ͜Ζ͋Γ·͢ͷͰɺৄࡉAWSͷϖʔδΛࢀর ʲσʔλͷݟ͑ΔԽʗ௨ʳ˞20197݄࣮ -
ϥϯχϯάίετ αʔϏε ྉۚ ༻ྔ ྉۚମܥ උߟ "84*P5$PSF 0QFSBUJPOT %FWJDF4IBEPXBOE%FWJDF3FHJTUSZ
0QFSBUJPOTɿສ͝ͱ ˞ ଞͷྉۚԁͷͨΊׂѪ -BNCEB ˞ "NB[PO4JNQMF 4UPSBHF4FSWJDF 165ଞ·Ͱɿ (&5ଞ·Ͱɿ ࠷ॳͷ5#݄·Ͱɿ(# ˞ ߹ܭ AWS ※౦ژϦʔδϣϯͷྉۚͰ͢ ※ྉۚମܥলུͯ͠Δͱ͜Ζ͋Γ·͢ͷͰɺৄࡉAWSͷϖʔδΛࢀর ※LambdaɺS3ʹ͍ͭͯɺଞαʔϏεͰ༻͍ͯ͠ΔͨΊਪఆʢσʔλͷݟ͑ΔԽʗ௨ΑΓ༻ྉগͳ͍ʣ ʲࢹʳ˞20197݄࣮ -
ϥϯχϯάίετ ϓϥϯ ྉۚ උߟ '3&&ϥΠηϯε ແྉ Ұ෦ɺػೳ੍ݶ͋Γ %&7&-01&3 ݄ʙ &YUFSOBM"DUJWF6TFSTʹΑΓมಈ
%&7&-01&3130 ˈ݄ʙ &YUFSOBM"DUJWF6TFSTଞʹΑΓมಈ Auth0 ※DEVELOPER PROͷ্ʹʮENTERPRISEʯϥΠηϯε͕͋Γ·ׂ͕͢Ѫ FREEϥΠηϯεͳͷͰɺ0ԁ ʲσʔλͷݟ͑ΔԽʳ -
ϥϯχϯάίετ HEROKU FreeͳͷͰ0ԁ ༻ऀेਓͰͦΕ΄ͲසൟʹΞΫηε͞ΕΔ༁Ͱͳ͍ͷͰFreeͰे ʲdyno https://jp.heroku.com/pricing#dynosʳ ϓϥϯ ྉۚ උߟ 'SFF
ແྉ Ұ෦ɺػೳ੍ݶ͋Γ )PCCZ ࠷େ݄EZOP ඵ୯Ґͷ՝ۚ 4UBOEBSE ࠷େ݄EZOP ඵ୯Ґͷ՝ۚ 1FSGPSNBODF ʲσʔλͷݟ͑ΔԽʳ -
ϥϯχϯάίετ HEROKU Hobby-FreeͳͷͰ0ԁ ηϯγϯάσʔλAWSʹ͋ΔͷͰHobby - FreeͰे ʲHeroku Postgres https://jp.heroku.com/pricing#databasesʳ ϓϥϯ
ྉۚ උߟ )PCCZ'SFF ແྉ ߦ·Ͱ )PCCZ#BTJD ࠷େ݄ ສߦ·Ͱ ඵ୯Ґͷ՝ۚ 4UBOEBSE ࠷େ ݄ ඵ୯Ґͷ՝ۚ 1SFNJVN ࠷େ ݄ ඵ୯Ґͷ՝ۚ ʲσʔλͷݟ͑ΔԽʳ -
ঢ়ଶͷมߋ AWS IoT Core AWS Lambda Amazon DynamoDB AWS Lambda
Amazon API Gateway Amazon Simple Storage Service આ໌ࡁΈ આ໌ࡁΈ -
σόΠεଆ cronͰຖਖ਼࣌ɺ5͝ͱىಈ ىಈ͝ͱDevice ShadowΛࢀর Device Shadow ΧϝϥͷࡱӨ༗ແʢis_shootingʣ trueɿࡱӨ͢Δ falseɿࡱӨ͠ͳ͍ Device
ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 } "camera": { "is_shooting": true } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 } "camera": { "is_shooting": true } }, # ΫϥυͱσόΠεͷࠩ } ঢ়ଶͷมߋ -
AWS IoT Core ঢ়ଶͷมߋ ҉͘ͳͬͨΒՄࢹޫΧϝϥͷࡱӨΛΊΔ Ϋϥυ σόΠε Device ShadowαʔϏε {
# Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 }, “camera": { “is_shooting": true } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 }, “camera": { “is_shooting": true } }, } ໌Δ͞Λૹ৴ ໌Δ͞ʹ0ʢਅͬ҉ʣ LambdaΛ࣮ߦ ਅͬ҉ʹͳͬͨͷͰShadowΛߋ৽ is_shootingΛʮfalseʯ -
AWS IoT Core ঢ়ଶͷมߋ ҉͘ͳͬͨΒՄࢹޫΧϝϥͷࡱӨΛΊΔ Ϋϥυ σόΠε Device ShadowαʔϏε {
# Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 }, “camera": { “is_shooting": false } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 }, “camera": { “is_shooting": true } }, # ΫϥυͱσόΠεͷࠩ “delta": { “camera": { “is_shooting": false } } } ໌Δ͞Λૹ৴ ໌Δ͞ʹ0ʢਅͬ҉ʣ LambdaΛ࣮ߦ ਅͬ҉ʹͳͬͨͷͰShadowΛߋ৽ is_shootingΛʮfalseʯ -
AWS IoT Core ঢ়ଶͷมߋ ҉͘ͳͬͨΒՄࢹޫΧϝϥͷࡱӨΛΊΔ Ϋϥυ σόΠε Device ShadowαʔϏε
Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 }, "camera": { "is_shooting": false } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 }, "camera": { "is_shooting": true } }, # ΫϥυͱσόΠεͷࠩ "delta": { "camera": { "is_shooting": false } } } ࠩΛreportedͱͯ͠ JSONͰૹΔʢUPDATEʣ JSONΛड͚औΔ GETཁٻ is_shooting͕false ͳͷͰࡱӨ͠ͳ͍ ໌Δ͞Λૹ৴ ໌Δ͞ʹ0ʢਅͬ҉ʣ LambdaΛ࣮ߦ ਅͬ҉ʹͳͬͨͷͰShadowΛߋ৽ is_shootingΛʮfalseʯ -
AWS IoT Core ঢ়ଶͷมߋ ҉͘ͳͬͨΒՄࢹޫΧϝϥͷࡱӨΛΊΔ Ϋϥυ σόΠε Device ShadowαʔϏε
Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 }, "camera": { "is_shooting": false } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 }, "camera": { "is_shooting": false } } # ΫϥυͱσόΠεͷࠩ } ࠩΛreportedͱͯ͠ JSONͰૹΔʢUPDATEʣ JSONΛड͚औΔ GETཁٻ is_shooting͕false ͳͷͰࡱӨ͠ͳ͍ ໌Δ͞Λૹ৴ ໌Δ͞ʹ0ʢਅͬ҉ʣ LambdaΛ࣮ߦ ਅͬ҉ʹͳͬͨͷͰShadowΛߋ৽ is_shootingΛʮfalseʯ -
AWS IoT Core ঢ়ଶͷมߋ ҉͘ͳͬͨΒՄࢹޫΧϝϥͷࡱӨΛΊΔ Ϋϥυ σόΠε Device ShadowαʔϏε
Device ShadowαʔϏε { # Ϋϥυ͔Βͷཁٻ "desired": { "sensor": { "interval": 10 }, "camera": { "is_shooting": false } }, # σόΠεͷঢ়ଶ "reported": { "sensor": { "interval": 10 }, "camera": { "is_shooting": false } } # ΫϥυͱσόΠεͷࠩ } ࠩΛreportedͱͯ͠ JSONͰૹΔʢUPDATEʣ JSONΛड͚औΔ GETཁٻ is_shooting͕false ͳͷͰࡱӨ͠ͳ͍ ໌Δ͞Λૹ৴ ໌Δ͞ʹ0ʢਅͬ҉ʣ LambdaΛ࣮ߦ ਅͬ҉ʹͳͬͨͷͰShadowΛߋ৽ is_shootingΛʮfalseʯ ͲͷΑ͏ʹ Device Shadow Λมߋ͍ͯ͠Δ͔ -
ঢ়ଶͷมߋ ҉͘ͳͬͨΒՄࢹޫΧϝϥͷࡱӨΛΊΔ import boto3 # IoTDataPlaneΫϥΠΞϯτ iot_data = boto3.client('iot-data') #
ࡱӨ͠ͳ͍ʹ͢Δ update_payload = b'{"state": {"desired": {"camera": {"is_shooting": false}}}}' # ShadowΛUPDATE͢Δ iot_data.update_thing_shadow( thingName=thing_name, payload=update_payload ) -
ঢ়ଶͷมߋ ͪͳΈʹDevice Shadowͷऔಘ؆୯ import boto3 # IoTDataPlaneΫϥΠΞϯτ iot_data = boto3.client('iot-data')
# shadow ͷऔಘ response = iot_data.get_thing_shadow( thingName=thing_name ) payload = response['payload'] payload_dict = json.loads(payload.read()) -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/ apigateway-use-lambda-authorizer.html AWS Lambda Amazon
API Gateway Amazon DynamoDB ΞΫηε੍ݶͳ͠ͷ߹ -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ʲϨεϙϯεʳDynamoDBొͨ͠σʔλ [ { “imsi": XXXX, “timestamp": 1565276403000, “air_quality”: 83, “humi": 41.8, “loudness": 88, “lux": 35, “temp": 25.3, }, ɾɾɾ ] ΞΫηε੍ݶͳ͠ͷ߹ -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ʲϨεϙϯεʳDynamoDBొͨ͠σʔλ [ { “imsi": XXXX, “timestamp": 1565276403000, “air_quality”: 83, “humi": 41.8, “loudness": 88, “lux": 35, “temp": 25.3, }, ɾɾɾ ] ΞΫηε੍ݶͳ͠ͷ߹ URLΛ͍ͬͯΔͱ୭ͰΞΫηεͰ͖ ͯ͠·͏ -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ΞΫηε੍ݶ͋Γͷ߹ -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ ೝূOK -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ ʲϨεϙϯεʳDynamoDBొͨ͠σʔλ [ { “imsi": XXXX, “timestamp": 1565276403000, “air_quality”: 83, “humi": 41.8, “loudness": 88, “lux": 35, “temp": 25.3, }, ɾɾɾ ] ೝূOK -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ ʲϨεϙϯεʳDynamoDBొͨ͠σʔλ [ { “imsi": XXXX, “timestamp": 1565276403000, “air_quality”: 83, “humi": 41.8, “loudness": 88, “lux": 35, “temp": 25.3, }, ɾɾɾ ] ೝূOK -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ ೝূNG -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ ೝূNG ޙଓͷLambda࣮ߦ͞Εͣ ݖݶͳ͕͠ฦ٫͞ΕΔ -
ΞΫηε੍ݶ API Gateway Lambda ΦʔιϥΠβʔͱ AWS Lambda Amazon API Gateway
Amazon DynamoDB ΞΫηε੍ݶ͋Γͷ߹ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ ޙଓͷLambda࣮ߦ͞Εͣ ݖݶͳ͕͠ฦ٫͞ΕΔ τʔΫϯͷൃߦʁ -
ΞΫηε੍ݶ Auth0Λར༻ Amazon API Gateway ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ Auth0 ϦΫΤετલʹ
τʔΫϯऔಘ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ -
ΞΫηε੍ݶ Auth0Λར༻ Amazon API Gateway ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ Auth0 ϦΫΤετલʹ
τʔΫϯऔಘ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ϦΫΤετͷ τʔΫϯΛೝূ -
ΞΫηε੍ݶ Auth0Λར༻ Amazon API Gateway ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ Auth0 ϦΫΤετલʹ
τʔΫϯऔಘ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ϦΫΤετͷ τʔΫϯΛೝূ -
from auth0.v3.authentication import GetToken ɾɾɾ # τʔΫϯऔಘʹඞཁͳใʢAuth0ͷϖʔδ͔Βऔಘʣ domain = settings.AUTH0_DOMAIN
client_id = settings.AUTH0_CLIENT_ID client_secret = settings.AUTH0_CLIENT_SECRET api_audience = settings.API_AUDIENCE # τʔΫϯΛऔಘ get_token = GetToken(domain) token = get_token.client_credentials(client_id, client_secret, api_audience) ΞΫηε੍ݶ Auth0Λར༻ -
ΞΫηε੍ݶ Auth0Λར༻ Amazon API Gateway ೝূɺೝՄΛߦ͏Lambda Lambda ΦʔιϥΠβʔ Auth0 ϦΫΤετલʹ
τʔΫϯऔಘ ϦΫΤετ࣌ͷϔομʹ τʔΫϯΛͨͤΔʂ ϦΫΤετͷ τʔΫϯΛೝূ -
from jose import jwt ɾɾɾ try: payload = jwt.decode( token,
rsa_key, algorithms=ALGORITHMS, audience=API_AUDIENCE, issuer="https://" + AUTH0_DOMAIN + "/" ) except jwt.ExpiredSignatureError: raise AuthError({"code": "token_expired", "description": "token is expired"}, 401) except jwt.JWTClaimsError: raise AuthError({"code": "invalid_claims", "description": "incorrect claims, please check the audience and issuer"}, 401) except Exception: raise AuthError({"code": "invalid_header", "description": "Unable to parse authentication token."}, 401) ΞΫηε੍ݶ Auth0Λར༻