![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
V.06 11/3
Dependencies: FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts
Fork of ATT_AWS_IoT_demo by
PythonGUI/ATT_AWS_IoT_Demo_GUI.py@17:46780b2de3e4, 2016-12-02 (annotated)
- Committer:
- ampembeng
- Date:
- Fri Dec 02 22:49:17 2016 +0000
- Revision:
- 17:46780b2de3e4
- Child:
- 19:488dad1e168e
Added the Python script ATT_AWS_IoT_Demo_GUI.py which is used as part of this demo.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ampembeng | 17:46780b2de3e4 | 1 | ''' |
ampembeng | 17:46780b2de3e4 | 2 | /* |
ampembeng | 17:46780b2de3e4 | 3 | * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
ampembeng | 17:46780b2de3e4 | 4 | * |
ampembeng | 17:46780b2de3e4 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"). |
ampembeng | 17:46780b2de3e4 | 6 | * You may not use this file except in compliance with the License. |
ampembeng | 17:46780b2de3e4 | 7 | * A copy of the License is located at |
ampembeng | 17:46780b2de3e4 | 8 | * |
ampembeng | 17:46780b2de3e4 | 9 | * http://aws.amazon.com/apache2.0 |
ampembeng | 17:46780b2de3e4 | 10 | * |
ampembeng | 17:46780b2de3e4 | 11 | * or in the "license" file accompanying this file. This file is distributed |
ampembeng | 17:46780b2de3e4 | 12 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
ampembeng | 17:46780b2de3e4 | 13 | * express or implied. See the License for the specific language governing |
ampembeng | 17:46780b2de3e4 | 14 | * permissions and limitations under the License. |
ampembeng | 17:46780b2de3e4 | 15 | */ |
ampembeng | 17:46780b2de3e4 | 16 | ''' |
ampembeng | 17:46780b2de3e4 | 17 | |
ampembeng | 17:46780b2de3e4 | 18 | from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient |
ampembeng | 17:46780b2de3e4 | 19 | import sys |
ampembeng | 17:46780b2de3e4 | 20 | import os.path |
ampembeng | 17:46780b2de3e4 | 21 | import logging |
ampembeng | 17:46780b2de3e4 | 22 | import time |
ampembeng | 17:46780b2de3e4 | 23 | import json |
ampembeng | 17:46780b2de3e4 | 24 | import getopt |
ampembeng | 17:46780b2de3e4 | 25 | import Tkinter |
ampembeng | 17:46780b2de3e4 | 26 | import tkFont |
ampembeng | 17:46780b2de3e4 | 27 | import time |
ampembeng | 17:46780b2de3e4 | 28 | from threading import Timer |
ampembeng | 17:46780b2de3e4 | 29 | from Tkinter import * |
ampembeng | 17:46780b2de3e4 | 30 | |
ampembeng | 17:46780b2de3e4 | 31 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 32 | # |
ampembeng | 17:46780b2de3e4 | 33 | # Set up our Tkinter based GUI |
ampembeng | 17:46780b2de3e4 | 34 | # |
ampembeng | 17:46780b2de3e4 | 35 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 36 | accepted = ["0", "1", "2", "4", "7"] |
ampembeng | 17:46780b2de3e4 | 37 | colorDict = {0 : 'off', 1 : 'red', 2 : 'green', 4 : "blue", 7 : "white"} |
ampembeng | 17:46780b2de3e4 | 38 | |
ampembeng | 17:46780b2de3e4 | 39 | window = Tkinter.Tk() |
ampembeng | 17:46780b2de3e4 | 40 | window.wm_title("AT&T AWS IoT Demo") |
ampembeng | 17:46780b2de3e4 | 41 | |
ampembeng | 17:46780b2de3e4 | 42 | topframe = Frame(window) |
ampembeng | 17:46780b2de3e4 | 43 | topframe.pack() |
ampembeng | 17:46780b2de3e4 | 44 | bottomframe = Frame(window) |
ampembeng | 17:46780b2de3e4 | 45 | bottomframe.pack( side = BOTTOM ) |
ampembeng | 17:46780b2de3e4 | 46 | |
ampembeng | 17:46780b2de3e4 | 47 | statusLabel = StringVar() |
ampembeng | 17:46780b2de3e4 | 48 | statusString = StringVar() |
ampembeng | 17:46780b2de3e4 | 49 | |
ampembeng | 17:46780b2de3e4 | 50 | # Control callbacks |
ampembeng | 17:46780b2de3e4 | 51 | def setStatus(statusStr): |
ampembeng | 17:46780b2de3e4 | 52 | if(statusString == statusStr): |
ampembeng | 17:46780b2de3e4 | 53 | statusString.set("unknown") |
ampembeng | 17:46780b2de3e4 | 54 | else: |
ampembeng | 17:46780b2de3e4 | 55 | statusString.set(statusStr) |
ampembeng | 17:46780b2de3e4 | 56 | |
ampembeng | 17:46780b2de3e4 | 57 | def offButtonCallBack(): |
ampembeng | 17:46780b2de3e4 | 58 | sendLEDRequest("0") |
ampembeng | 17:46780b2de3e4 | 59 | |
ampembeng | 17:46780b2de3e4 | 60 | def redButtonCallBack(): |
ampembeng | 17:46780b2de3e4 | 61 | sendLEDRequest("1") |
ampembeng | 17:46780b2de3e4 | 62 | |
ampembeng | 17:46780b2de3e4 | 63 | def greenButtonCallBack(): |
ampembeng | 17:46780b2de3e4 | 64 | sendLEDRequest("2") |
ampembeng | 17:46780b2de3e4 | 65 | |
ampembeng | 17:46780b2de3e4 | 66 | def blueButtonCallBack(): |
ampembeng | 17:46780b2de3e4 | 67 | sendLEDRequest("4") |
ampembeng | 17:46780b2de3e4 | 68 | |
ampembeng | 17:46780b2de3e4 | 69 | def whiteButtonCallBack(): |
ampembeng | 17:46780b2de3e4 | 70 | sendLEDRequest("7") |
ampembeng | 17:46780b2de3e4 | 71 | |
ampembeng | 17:46780b2de3e4 | 72 | # Create our Labels |
ampembeng | 17:46780b2de3e4 | 73 | StaticLabel = Label(topframe, textvariable=statusLabel, relief=FLAT) |
ampembeng | 17:46780b2de3e4 | 74 | statusLabel.set("AWS Reported LED Status: ") |
ampembeng | 17:46780b2de3e4 | 75 | |
ampembeng | 17:46780b2de3e4 | 76 | StatusLabel = Label(topframe, textvariable=statusString, relief=FLAT) |
ampembeng | 17:46780b2de3e4 | 77 | statusString.set("unknown (needs to sync)") |
ampembeng | 17:46780b2de3e4 | 78 | |
ampembeng | 17:46780b2de3e4 | 79 | # Create our Buttons |
ampembeng | 17:46780b2de3e4 | 80 | O = Tkinter.Button(bottomframe, text ="Off", fg="gray", bg="black", command = offButtonCallBack) |
ampembeng | 17:46780b2de3e4 | 81 | R = Tkinter.Button(bottomframe, text ="R", fg="gray", bg="red", command = redButtonCallBack) |
ampembeng | 17:46780b2de3e4 | 82 | G = Tkinter.Button(bottomframe, text ="G", fg="gray", bg="green", command = greenButtonCallBack) |
ampembeng | 17:46780b2de3e4 | 83 | B = Tkinter.Button(bottomframe, text ="B", fg="gray", bg="blue", command = blueButtonCallBack) |
ampembeng | 17:46780b2de3e4 | 84 | W = Tkinter.Button(bottomframe, text ="W", fg="gray", bg="white", command = whiteButtonCallBack) |
ampembeng | 17:46780b2de3e4 | 85 | |
ampembeng | 17:46780b2de3e4 | 86 | # Set font |
ampembeng | 17:46780b2de3e4 | 87 | font = tkFont.Font(family='Times', size=24, weight='bold') |
ampembeng | 17:46780b2de3e4 | 88 | O['font'] = font |
ampembeng | 17:46780b2de3e4 | 89 | R['font'] = font |
ampembeng | 17:46780b2de3e4 | 90 | G['font'] = font |
ampembeng | 17:46780b2de3e4 | 91 | B['font'] = font |
ampembeng | 17:46780b2de3e4 | 92 | W['font'] = font |
ampembeng | 17:46780b2de3e4 | 93 | |
ampembeng | 17:46780b2de3e4 | 94 | # Arrange our controls |
ampembeng | 17:46780b2de3e4 | 95 | StaticLabel.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 96 | StatusLabel.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 97 | O.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 98 | R.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 99 | G.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 100 | B.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 101 | W.pack(side = LEFT) |
ampembeng | 17:46780b2de3e4 | 102 | |
ampembeng | 17:46780b2de3e4 | 103 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 104 | # |
ampembeng | 17:46780b2de3e4 | 105 | # These functions are for AWS |
ampembeng | 17:46780b2de3e4 | 106 | # |
ampembeng | 17:46780b2de3e4 | 107 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 108 | # Shadow JSON schema: |
ampembeng | 17:46780b2de3e4 | 109 | # |
ampembeng | 17:46780b2de3e4 | 110 | # Name: Bot |
ampembeng | 17:46780b2de3e4 | 111 | # { |
ampembeng | 17:46780b2de3e4 | 112 | # "state": { |
ampembeng | 17:46780b2de3e4 | 113 | # "desired":{ |
ampembeng | 17:46780b2de3e4 | 114 | # "ledColor":<INT VALUE> |
ampembeng | 17:46780b2de3e4 | 115 | # } |
ampembeng | 17:46780b2de3e4 | 116 | # } |
ampembeng | 17:46780b2de3e4 | 117 | #} |
ampembeng | 17:46780b2de3e4 | 118 | |
ampembeng | 17:46780b2de3e4 | 119 | def sendLEDRequest(color_input): |
ampembeng | 17:46780b2de3e4 | 120 | if (color_input in accepted): |
ampembeng | 17:46780b2de3e4 | 121 | JSONPayload = '{"state":{"desired":{"ledColor":' + str(color_input) + '}}}' |
ampembeng | 17:46780b2de3e4 | 122 | Bot.shadowUpdate(JSONPayload, customShadowCallback_Update, 5) |
ampembeng | 17:46780b2de3e4 | 123 | else: |
ampembeng | 17:46780b2de3e4 | 124 | print("WARN: Color input invalid - " + color_input) |
ampembeng | 17:46780b2de3e4 | 125 | |
ampembeng | 17:46780b2de3e4 | 126 | # Custom Shadow callback |
ampembeng | 17:46780b2de3e4 | 127 | def customShadowCallback_Delta(payload, responseStatus, token): |
ampembeng | 17:46780b2de3e4 | 128 | # payload is a JSON string ready to be parsed using json.loads(...) |
ampembeng | 17:46780b2de3e4 | 129 | # in both Py2.x and Py3.x |
ampembeng | 17:46780b2de3e4 | 130 | print(responseStatus) |
ampembeng | 17:46780b2de3e4 | 131 | payloadDict = json.loads(payload) |
ampembeng | 17:46780b2de3e4 | 132 | print("++++++++DELTA++++++++++") |
ampembeng | 17:46780b2de3e4 | 133 | print("ledColor: " + str(payloadDict["state"]["ledColor"])) |
ampembeng | 17:46780b2de3e4 | 134 | print("version: " + str(payloadDict["version"])) |
ampembeng | 17:46780b2de3e4 | 135 | print("+++++++++++++++++++++++\n\n") |
ampembeng | 17:46780b2de3e4 | 136 | |
ampembeng | 17:46780b2de3e4 | 137 | # Send payload to our status |
ampembeng | 17:46780b2de3e4 | 138 | setStatus(colorDict[payloadDict["state"]["ledColor"]]) |
ampembeng | 17:46780b2de3e4 | 139 | |
ampembeng | 17:46780b2de3e4 | 140 | # Custom Shadow callback |
ampembeng | 17:46780b2de3e4 | 141 | def customShadowCallback_Update(payload, responseStatus, token): |
ampembeng | 17:46780b2de3e4 | 142 | # payload is a JSON string ready to be parsed using json.loads(...) |
ampembeng | 17:46780b2de3e4 | 143 | # in both Py2.x and Py3.x |
ampembeng | 17:46780b2de3e4 | 144 | if responseStatus == "timeout": |
ampembeng | 17:46780b2de3e4 | 145 | print("Update request " + token + " time out!") |
ampembeng | 17:46780b2de3e4 | 146 | if responseStatus == "accepted": |
ampembeng | 17:46780b2de3e4 | 147 | payloadDict = json.loads(payload) |
ampembeng | 17:46780b2de3e4 | 148 | print("~~~~~~~~~~~~~~~~~~~~~~~") |
ampembeng | 17:46780b2de3e4 | 149 | print("Update request with token: " + token + " accepted!") |
ampembeng | 17:46780b2de3e4 | 150 | print("ledColor: " + str(payloadDict["state"]["desired"]["ledColor"])) |
ampembeng | 17:46780b2de3e4 | 151 | print("~~~~~~~~~~~~~~~~~~~~~~~\n\n") |
ampembeng | 17:46780b2de3e4 | 152 | if responseStatus == "rejected": |
ampembeng | 17:46780b2de3e4 | 153 | print("Update request " + token + " rejected!") |
ampembeng | 17:46780b2de3e4 | 154 | |
ampembeng | 17:46780b2de3e4 | 155 | def customShadowCallback_Delete(payload, responseStatus, token): |
ampembeng | 17:46780b2de3e4 | 156 | if responseStatus == "timeout": |
ampembeng | 17:46780b2de3e4 | 157 | print("Delete request " + token + " time out!") |
ampembeng | 17:46780b2de3e4 | 158 | if responseStatus == "accepted": |
ampembeng | 17:46780b2de3e4 | 159 | print("~~~~~~~~~~~~~~~~~~~~~~~") |
ampembeng | 17:46780b2de3e4 | 160 | print("Delete request with token: " + token + " accepted!") |
ampembeng | 17:46780b2de3e4 | 161 | print("~~~~~~~~~~~~~~~~~~~~~~~\n\n") |
ampembeng | 17:46780b2de3e4 | 162 | if responseStatus == "rejected": |
ampembeng | 17:46780b2de3e4 | 163 | print("Delete request " + token + " rejected!") |
ampembeng | 17:46780b2de3e4 | 164 | |
ampembeng | 17:46780b2de3e4 | 165 | # Custom Shadow callback |
ampembeng | 17:46780b2de3e4 | 166 | def customShadowCallback_Get(payload, responseStatus, token): |
ampembeng | 17:46780b2de3e4 | 167 | print(responseStatus) |
ampembeng | 17:46780b2de3e4 | 168 | payloadDict = json.loads(payload) |
ampembeng | 17:46780b2de3e4 | 169 | reportedColor = payloadDict["state"]["reported"]["ledColor"] |
ampembeng | 17:46780b2de3e4 | 170 | print("++++++++GET++++++++++") |
ampembeng | 17:46780b2de3e4 | 171 | print("ledColor: " + str(reportedColor) + " (" + colorDict[reportedColor] + ")") |
ampembeng | 17:46780b2de3e4 | 172 | print("version: " + str(payloadDict["version"])) |
ampembeng | 17:46780b2de3e4 | 173 | print("+++++++++++++++++++++\n\n") |
ampembeng | 17:46780b2de3e4 | 174 | |
ampembeng | 17:46780b2de3e4 | 175 | # Send payload to our status |
ampembeng | 17:46780b2de3e4 | 176 | setStatus(colorDict[reportedColor]) |
ampembeng | 17:46780b2de3e4 | 177 | |
ampembeng | 17:46780b2de3e4 | 178 | getTimerAlive = TRUE |
ampembeng | 17:46780b2de3e4 | 179 | def customShadowTimer_Get(): |
ampembeng | 17:46780b2de3e4 | 180 | while (getTimerAlive): |
ampembeng | 17:46780b2de3e4 | 181 | Bot.shadowGet(customShadowCallback_Get, 5) |
ampembeng | 17:46780b2de3e4 | 182 | time.sleep(3) |
ampembeng | 17:46780b2de3e4 | 183 | |
ampembeng | 17:46780b2de3e4 | 184 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 185 | # |
ampembeng | 17:46780b2de3e4 | 186 | # Vars |
ampembeng | 17:46780b2de3e4 | 187 | # |
ampembeng | 17:46780b2de3e4 | 188 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 189 | # Usage |
ampembeng | 17:46780b2de3e4 | 190 | usageInfo = """Usage: |
ampembeng | 17:46780b2de3e4 | 191 | |
ampembeng | 17:46780b2de3e4 | 192 | Use certificate based mutual authentication: |
ampembeng | 17:46780b2de3e4 | 193 | python basicShadowDeltaListener.py -e <endpoint> -r <rootCAFilePath> -c <certFilePath> -k <privateKeyFilePath> |
ampembeng | 17:46780b2de3e4 | 194 | |
ampembeng | 17:46780b2de3e4 | 195 | Use MQTT over WebSocket: |
ampembeng | 17:46780b2de3e4 | 196 | python basicShadowDeltaListener.py -e <endpoint> -r <rootCAFilePath> -w |
ampembeng | 17:46780b2de3e4 | 197 | |
ampembeng | 17:46780b2de3e4 | 198 | Type "python basicShadowDeltaListener.py -h" for available options. |
ampembeng | 17:46780b2de3e4 | 199 | |
ampembeng | 17:46780b2de3e4 | 200 | |
ampembeng | 17:46780b2de3e4 | 201 | """ |
ampembeng | 17:46780b2de3e4 | 202 | # Help info |
ampembeng | 17:46780b2de3e4 | 203 | helpInfo = """-e, --endpoint |
ampembeng | 17:46780b2de3e4 | 204 | Your AWS IoT custom endpoint |
ampembeng | 17:46780b2de3e4 | 205 | -r, --rootCA |
ampembeng | 17:46780b2de3e4 | 206 | Root CA file path |
ampembeng | 17:46780b2de3e4 | 207 | -c, --cert |
ampembeng | 17:46780b2de3e4 | 208 | Certificate file path |
ampembeng | 17:46780b2de3e4 | 209 | -k, --key |
ampembeng | 17:46780b2de3e4 | 210 | Private key file path |
ampembeng | 17:46780b2de3e4 | 211 | -w, --websocket |
ampembeng | 17:46780b2de3e4 | 212 | Use MQTT over WebSocket |
ampembeng | 17:46780b2de3e4 | 213 | -h, --help |
ampembeng | 17:46780b2de3e4 | 214 | Help information |
ampembeng | 17:46780b2de3e4 | 215 | |
ampembeng | 17:46780b2de3e4 | 216 | |
ampembeng | 17:46780b2de3e4 | 217 | """ |
ampembeng | 17:46780b2de3e4 | 218 | |
ampembeng | 17:46780b2de3e4 | 219 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 220 | # |
ampembeng | 17:46780b2de3e4 | 221 | # AWS IoT Config Parameters. The user needs to enter these (they should match the parameters in aws_iot_config.h) |
ampembeng | 17:46780b2de3e4 | 222 | # |
ampembeng | 17:46780b2de3e4 | 223 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 224 | useWebsocket = False |
ampembeng | 17:46780b2de3e4 | 225 | # TODO Move params to aws_iot_config.txt |
ampembeng | 17:46780b2de3e4 | 226 | AWS_IOT_MQTT_HOST = "a3sptpklzib7sa.iot.us-west-2.amazonaws.com" |
ampembeng | 17:46780b2de3e4 | 227 | AWS_IOT_MQTT_PORT = 8883 |
ampembeng | 17:46780b2de3e4 | 228 | AWS_IOT_MQTT_CLIENT_ID = "EesFRDM" |
ampembeng | 17:46780b2de3e4 | 229 | AWS_IOT_MY_THING_NAME = "EesFRDM" |
ampembeng | 17:46780b2de3e4 | 230 | AWS_IOT_ROOT_CA_FILENAME = "C:/Temp/certs/rootCA-certificate.crt" |
ampembeng | 17:46780b2de3e4 | 231 | AWS_IOT_PRIVATE_KEY_FILENAME = "C:/Temp/certs/private.pem.key" |
ampembeng | 17:46780b2de3e4 | 232 | AWS_IOT_CERTIFICATE_FILENAME = "C:/Temp/certs/certificate.pem.crt" |
ampembeng | 17:46780b2de3e4 | 233 | |
ampembeng | 17:46780b2de3e4 | 234 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 235 | # |
ampembeng | 17:46780b2de3e4 | 236 | # Arg Parser |
ampembeng | 17:46780b2de3e4 | 237 | # |
ampembeng | 17:46780b2de3e4 | 238 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 239 | ''' |
ampembeng | 17:46780b2de3e4 | 240 | try: |
ampembeng | 17:46780b2de3e4 | 241 | opts, args = getopt.getopt(sys.argv[1:], "hwe:k:c:r:", ["help", "endpoint=", "key=","cert=","rootCA=", "websocket"]) |
ampembeng | 17:46780b2de3e4 | 242 | if len(opts) == 0: |
ampembeng | 17:46780b2de3e4 | 243 | raise getopt.GetoptError("No input parameters!") |
ampembeng | 17:46780b2de3e4 | 244 | for opt, arg in opts: |
ampembeng | 17:46780b2de3e4 | 245 | if opt in ("-h", "--help"): |
ampembeng | 17:46780b2de3e4 | 246 | print(helpInfo) |
ampembeng | 17:46780b2de3e4 | 247 | exit(0) |
ampembeng | 17:46780b2de3e4 | 248 | if opt in ("-e", "--endpoint"): |
ampembeng | 17:46780b2de3e4 | 249 | AWS_IOT_MQTT_HOST = arg |
ampembeng | 17:46780b2de3e4 | 250 | if opt in ("-r", "--rootCA"): |
ampembeng | 17:46780b2de3e4 | 251 | AWS_IOT_ROOT_CA_FILENAME = arg |
ampembeng | 17:46780b2de3e4 | 252 | if opt in ("-c", "--cert"): |
ampembeng | 17:46780b2de3e4 | 253 | AWS_IOT_CERTIFICATE_FILENAME = arg |
ampembeng | 17:46780b2de3e4 | 254 | if opt in ("-k", "--key"): |
ampembeng | 17:46780b2de3e4 | 255 | AWS_IOT_PRIVATE_KEY_FILENAME = arg |
ampembeng | 17:46780b2de3e4 | 256 | if opt in ("-w", "--websocket"): |
ampembeng | 17:46780b2de3e4 | 257 | useWebsocket = True |
ampembeng | 17:46780b2de3e4 | 258 | except getopt.GetoptError: |
ampembeng | 17:46780b2de3e4 | 259 | print(usageInfo) |
ampembeng | 17:46780b2de3e4 | 260 | #exit(1) |
ampembeng | 17:46780b2de3e4 | 261 | |
ampembeng | 17:46780b2de3e4 | 262 | # Missing configuration notification |
ampembeng | 17:46780b2de3e4 | 263 | missingConfiguration = False |
ampembeng | 17:46780b2de3e4 | 264 | if not AWS_IOT_MQTT_HOST: |
ampembeng | 17:46780b2de3e4 | 265 | print("Missing '-e' or '--endpoint'") |
ampembeng | 17:46780b2de3e4 | 266 | missingConfiguration = True |
ampembeng | 17:46780b2de3e4 | 267 | if not AWS_IOT_ROOT_CA_FILENAME: |
ampembeng | 17:46780b2de3e4 | 268 | print("Missing '-r' or '--rootCA'") |
ampembeng | 17:46780b2de3e4 | 269 | missingConfiguration = True |
ampembeng | 17:46780b2de3e4 | 270 | if not useWebsocket: |
ampembeng | 17:46780b2de3e4 | 271 | if not AWS_IOT_CERTIFICATE_FILENAME: |
ampembeng | 17:46780b2de3e4 | 272 | print("Missing '-c' or '--cert'") |
ampembeng | 17:46780b2de3e4 | 273 | missingConfiguration = True |
ampembeng | 17:46780b2de3e4 | 274 | if not AWS_IOT_PRIVATE_KEY_FILENAME: |
ampembeng | 17:46780b2de3e4 | 275 | print("Missing '-k' or '--key'") |
ampembeng | 17:46780b2de3e4 | 276 | missingConfiguration = True |
ampembeng | 17:46780b2de3e4 | 277 | if missingConfiguration: |
ampembeng | 17:46780b2de3e4 | 278 | exit(2) |
ampembeng | 17:46780b2de3e4 | 279 | ''' |
ampembeng | 17:46780b2de3e4 | 280 | |
ampembeng | 17:46780b2de3e4 | 281 | # Configure logging |
ampembeng | 17:46780b2de3e4 | 282 | logger = logging.getLogger("AWSIoTPythonSDK.core") |
ampembeng | 17:46780b2de3e4 | 283 | logger.setLevel(logging.DEBUG) |
ampembeng | 17:46780b2de3e4 | 284 | streamHandler = logging.StreamHandler() |
ampembeng | 17:46780b2de3e4 | 285 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
ampembeng | 17:46780b2de3e4 | 286 | streamHandler.setFormatter(formatter) |
ampembeng | 17:46780b2de3e4 | 287 | logger.addHandler(streamHandler) |
ampembeng | 17:46780b2de3e4 | 288 | |
ampembeng | 17:46780b2de3e4 | 289 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 290 | # |
ampembeng | 17:46780b2de3e4 | 291 | # Main Code |
ampembeng | 17:46780b2de3e4 | 292 | # |
ampembeng | 17:46780b2de3e4 | 293 | ####################################################################################################################### |
ampembeng | 17:46780b2de3e4 | 294 | # Makes sure files exist |
ampembeng | 17:46780b2de3e4 | 295 | if not os.path.exists(AWS_IOT_ROOT_CA_FILENAME): |
ampembeng | 17:46780b2de3e4 | 296 | print "ERROR: Root CA file not found, " + AWS_IOT_ROOT_CA_FILENAME |
ampembeng | 17:46780b2de3e4 | 297 | exit(1) |
ampembeng | 17:46780b2de3e4 | 298 | if not os.path.exists(AWS_IOT_PRIVATE_KEY_FILENAME): |
ampembeng | 17:46780b2de3e4 | 299 | print "ERROR: Private Key file not found, " + AWS_IOT_PRIVATE_KEY_FILENAME |
ampembeng | 17:46780b2de3e4 | 300 | exit(1) |
ampembeng | 17:46780b2de3e4 | 301 | if not os.path.exists(AWS_IOT_CERTIFICATE_FILENAME): |
ampembeng | 17:46780b2de3e4 | 302 | print "ERROR: AWS IOT cert file not found, " + AWS_IOT_CERTIFICATE_FILENAME |
ampembeng | 17:46780b2de3e4 | 303 | exit(1) |
ampembeng | 17:46780b2de3e4 | 304 | |
ampembeng | 17:46780b2de3e4 | 305 | # Init AWSIoTMQTTShadowClient |
ampembeng | 17:46780b2de3e4 | 306 | myAWSIoTMQTTShadowClient = None |
ampembeng | 17:46780b2de3e4 | 307 | if useWebsocket: |
ampembeng | 17:46780b2de3e4 | 308 | myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient("basicShadowDeltaListener", useWebsocket=True) |
ampembeng | 17:46780b2de3e4 | 309 | myAWSIoTMQTTShadowClient.configureEndpoint(AWS_IOT_MQTT_HOST, 443) |
ampembeng | 17:46780b2de3e4 | 310 | myAWSIoTMQTTShadowClient.configureCredentials(AWS_IOT_ROOT_CA_FILENAME) |
ampembeng | 17:46780b2de3e4 | 311 | else: |
ampembeng | 17:46780b2de3e4 | 312 | myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient("basicShadowDeltaListener") |
ampembeng | 17:46780b2de3e4 | 313 | myAWSIoTMQTTShadowClient.configureEndpoint(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT) |
ampembeng | 17:46780b2de3e4 | 314 | myAWSIoTMQTTShadowClient.configureCredentials(AWS_IOT_ROOT_CA_FILENAME, AWS_IOT_PRIVATE_KEY_FILENAME, AWS_IOT_CERTIFICATE_FILENAME) |
ampembeng | 17:46780b2de3e4 | 315 | |
ampembeng | 17:46780b2de3e4 | 316 | # AWSIoTMQTTShadowClient configuration |
ampembeng | 17:46780b2de3e4 | 317 | myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) |
ampembeng | 17:46780b2de3e4 | 318 | myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec |
ampembeng | 17:46780b2de3e4 | 319 | myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec |
ampembeng | 17:46780b2de3e4 | 320 | |
ampembeng | 17:46780b2de3e4 | 321 | # Connect to AWS IoT |
ampembeng | 17:46780b2de3e4 | 322 | myAWSIoTMQTTShadowClient.connect() |
ampembeng | 17:46780b2de3e4 | 323 | |
ampembeng | 17:46780b2de3e4 | 324 | # Create a deviceShadow with persistent subscription |
ampembeng | 17:46780b2de3e4 | 325 | Bot = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(AWS_IOT_MY_THING_NAME, True) |
ampembeng | 17:46780b2de3e4 | 326 | |
ampembeng | 17:46780b2de3e4 | 327 | # Listen on deltas |
ampembeng | 17:46780b2de3e4 | 328 | Bot.shadowRegisterDeltaCallback(customShadowCallback_Delta) |
ampembeng | 17:46780b2de3e4 | 329 | |
ampembeng | 17:46780b2de3e4 | 330 | # Delete shadow JSON doc |
ampembeng | 17:46780b2de3e4 | 331 | #Bot.shadowDelete(customShadowCallback_Delete, 5) |
ampembeng | 17:46780b2de3e4 | 332 | |
ampembeng | 17:46780b2de3e4 | 333 | getTimer = Timer(3.0, customShadowTimer_Get, ()) |
ampembeng | 17:46780b2de3e4 | 334 | getTimer.start() |
ampembeng | 17:46780b2de3e4 | 335 | |
ampembeng | 17:46780b2de3e4 | 336 | # GUI loop (loops until closed) |
ampembeng | 17:46780b2de3e4 | 337 | window.mainloop() |
ampembeng | 17:46780b2de3e4 | 338 | |
ampembeng | 17:46780b2de3e4 | 339 | # Kill our timer after the GUI closes |
ampembeng | 17:46780b2de3e4 | 340 | getTimerAlive = FALSE |
ampembeng | 17:46780b2de3e4 | 341 | getTimer.cancel() |