AWS IoT demonstration using the Avnet Shield (AT&T LTE) and the FRDM-K64F target board.

Dependencies:   K64F_FATFileSystem

Fork of mbed-os-example-tls-tls-client by mbed-os-examples

Files at this revision

API Documentation at this revision

Comitter:
ampembeng
Date:
Mon Dec 19 20:52:28 2016 +0000
Parent:
24:224c07ec3bd0
Commit message:
Updated the look/feel of the Python GUI to match the AT&T locker demo S3 page. Added "assets" folder to support this. Updated the README.

Changed in this revision

PythonGUI/ATT_AWS_IoT_Demo_GUI.py Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/ATT_Icon.ico Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/LEDBlue.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/LEDGreen.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/LEDOff.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/LEDRed.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/LEDWhite.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/attLogo.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/awsLogo.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/startKitBoard.png Show annotated file Show diff for this revision Revisions of this file
PythonGUI/assets/starterKitBox.png Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
--- a/PythonGUI/ATT_AWS_IoT_Demo_GUI.py	Fri Dec 16 18:04:39 2016 +0000
+++ b/PythonGUI/ATT_AWS_IoT_Demo_GUI.py	Mon Dec 19 20:52:28 2016 +0000
@@ -28,6 +28,10 @@
 import time
 from threading import Timer
 from Tkinter import *
+from PIL import Image, ImageTk
+
+exePath = os.path.dirname(os.path.realpath(__file__))
+assetPath = exePath + "\\assets\\"
 
 #######################################################################################################################
 #
@@ -36,21 +40,51 @@
 #######################################################################################################################
 accepted = ["0", "1", "2", "4", "7"]
 colorDict = {0 : 'off', 1 : 'red', 2 : 'green', 4 : "blue", 7 : "white"}
+ledImgPaths = {0 : "LEDOff.png", 1 : 'LEDRed.png', 2 : 'LEDGreen.png', 4 : "LEDBlue.png", 7 : "LEDWhite.png"}
 
 window = Tkinter.Tk()
-window.wm_title("AT&T AWS IoT Demo")
+window.wm_title("AT&T AWS IoT Starter Kit Demo")
+window.iconbitmap(assetPath + "ATT_Icon.ico")
+window.resizable(width=False, height=False)
+
+buttonColor = 'dark slate gray'
+buttonTxtColor = 'tv white'
+headerBgColor = 'snow'
+bgColor = 'steel blue'
+fgTextColor = 'white'
 
 # Setup frames
-topframe = Frame(window)
-topframe.pack(fill=X, side = TOP)
-frameR1 = Frame(window)
-frameR1.pack(fill=X, side = TOP)
-frameR2 = Frame(window)
-frameR2.pack(fill=X, side = TOP)
-frameR3 = Frame(window)
-frameR3.pack(fill=X, side = TOP)
-bottomframe = Frame(window)
-bottomframe.pack(fill=X, side = BOTTOM)
+def initFrames(_window, side, color=bgColor):
+    frame = Frame(_window, background=color)
+    frame.pack(fill=X, side=side)
+    return frame
+
+headerframe = initFrames(window, TOP, headerBgColor)
+frameR1 = initFrames(window, TOP)
+frameR2 = initFrames(window, TOP)
+frameR3 = initFrames(window, TOP)
+frameR4 = initFrames(window, TOP)
+frameR5 = initFrames(window, TOP)
+frameR6 = initFrames(window, TOP)
+frameR7 = initFrames(window, TOP)
+frameR8 = initFrames(window, TOP)
+frameR9 = initFrames(window, TOP)
+buttonFrame = initFrames(window, BOTTOM)
+
+# So we can loop through our frames
+frameIndex = 0
+frames = [headerframe,
+          frameR1, frameR2, frameR3, frameR4, frameR5,
+          frameR6, frameR7, frameR8, frameR9,
+          buttonFrame]
+
+def curFrame():
+    return frames[frameIndex]
+
+def nextFrame():
+    global frameIndex
+    frameIndex += 1
+    return frames[frameIndex]
 
 # Label vars (controls shown text)
 ledStaticLabelTxt = StringVar()
@@ -67,17 +101,24 @@
 def setStatus(ledStatus, tempStatus, humidStatus, version):
     global versionLastValue
 
-    ledStatusLabelTxt.set(ledStatus)
+    ledStatusLabelTxt.set(colorDict[ledStatus])
+    updateLEDImage(ledImgPaths[ledStatus])
     tempStatusLabelTxt.set(str(tempStatus) + " (F)")
     humidStatusLabelTxt.set(str(humidStatus) + " %")
 
     isStale = ""
     if (versionLastValue == version):
-        isStale = " (stale)"
+        isStale = " (stale data)"
     else:
         versionLastValue = version
     versionStatusLabelTxt.set(str(version) + isStale)
 
+def updateLEDImage(path):
+    global ledPicture
+    img2 = ImageTk.PhotoImage(Image.open(assetPath + path))
+    ledPicture.configure(image=img2)
+    ledPicture.image = img2
+
 def offButtonCallBack():
     sendLEDRequest("0")
 
@@ -93,56 +134,80 @@
 def whiteButtonCallBack():
     sendLEDRequest("7")
 
+# Photos
+def initPhotoLabels(frame, photoName, color=bgColor, side=LEFT, pad=0):
+    image = Image.open(assetPath + photoName)
+    photo = ImageTk.PhotoImage(image)
+
+    label = Label(frame, image=photo, background=color)
+    label.image = photo  # keep a reference!
+    label.pack(side=side, padx=pad)
+    return label
+
 # Create our Labels
-ledStaticLabel = Label(topframe, textvariable=ledStaticLabelTxt, anchor=W, relief=FLAT)
-ledStaticLabelTxt.set("Reported LED Status: ")
-ledStatusLabel = Label(topframe, textvariable=ledStatusLabelTxt, anchor=W, relief=FLAT)
-ledStatusLabelTxt.set("unknown (needs to sync)")
+headerLabel1 = initPhotoLabels(curFrame(), "attLogo.png", headerBgColor)
+headerLabel2 = initPhotoLabels(curFrame(), "awsLogo.png", headerBgColor, pad=10)
+
+starterKitBoxLabel = initPhotoLabels(nextFrame(), "starterKitBox.png")
+
+labelFont = tkFont.Font(family='Times', size=14, weight='bold')
+def initLargeTextLabels(frame, text):
+    label = Label(frame, font=labelFont, text=text, anchor=W, relief=FLAT, fg=fgTextColor, background=bgColor)
+    label.pack(side=LEFT)
+
+setLEDColorLabel = initLargeTextLabels(nextFrame(),"Reported Values")
 
-tempStaticLabel = Label(frameR1, textvariable=tempStaticLabelTxt, anchor=W, relief=FLAT)
-tempStaticLabelTxt.set("Reported Temperature: ")
-tempStatusLabel = Label(frameR1, textvariable=tempStatusLabelTxt, anchor=W, relief=FLAT)
-tempStatusLabelTxt.set("unknown (needs to sync)")
+def initLabels(frame, lableVar, text):
+    lableVar.set(text)
+    label = Label(frame, textvariable=lableVar, anchor=W, relief=FLAT, fg=fgTextColor, background=bgColor)
+    label.pack(side = LEFT)
+    return label
+
+ledStaticLabel = initLabels(nextFrame(), ledStaticLabelTxt, "LED Color: ")
+ledStatusLabel = initLabels(curFrame(), ledStatusLabelTxt, "unknown (needs to sync)")
+
+tempStaticLabel = initLabels(nextFrame(), tempStaticLabelTxt, "Temperature: ")
+tempStatusLabel = initLabels(curFrame(), tempStatusLabelTxt, "unknown (needs to sync)")
 
-humidStaticLabel = Label(frameR2, textvariable=humidStaticLabelTxt, anchor=W, relief=FLAT)
-humidStaticLabelTxt.set("Reported Humidity: ")
-humidStatusLabel = Label(frameR2, textvariable=humidStatusLabelTxt, anchor=W, relief=FLAT)
-humidStatusLabelTxt.set("unknown (needs to sync)")
+humidStaticLabel = initLabels(nextFrame(), humidStaticLabelTxt, "Humidity: ")
+humidStatusLabel = initLabels(curFrame(), humidStatusLabelTxt, "unknown (needs to sync)")
+
+versionStaticLabel = initLabels(nextFrame(), versionStaticLabelTxt, "Shadow Version: ")
+versionStatusLabel = initLabels(curFrame(), versionStatusLabelTxt, "unknown (needs to sync)")
 
-versionStaticLabel = Label(frameR3, textvariable=versionStaticLabelTxt, anchor=W, relief=FLAT)
-versionStaticLabelTxt.set("IoT Shadow Version: ")
-versionStatusLabel = Label(frameR3, textvariable=versionStatusLabelTxt, anchor=W, relief=FLAT)
-versionStatusLabelTxt.set("unknown (needs to sync)")
+lineLabel = initLargeTextLabels(nextFrame(), "_______________________________________")
+setLEDColorLabel = initLargeTextLabels(nextFrame(),"Set LED Color")
+
+starterKitBoardLabel = initPhotoLabels(nextFrame(), "startKitBoard.png", side=TOP)
+
+# Creates an LED label (image) that we can update.
+ledPicture = Label(starterKitBoardLabel, background=bgColor, relief=FLAT, width=10, height=12)
+ledPicture.place(relx=1.0, rely=1.0, x=(40-300), y=(85-245), anchor="se")
+updateLEDImage("LEDOff.png")
 
 # Create our Buttons
-O = Tkinter.Button(bottomframe, text ="Off", fg="gray", bg="black", command = offButtonCallBack)
-R = Tkinter.Button(bottomframe, text ="R", fg="gray", bg="red", command = redButtonCallBack)
-G = Tkinter.Button(bottomframe, text ="G", fg="gray", bg="green", command = greenButtonCallBack)
-B = Tkinter.Button(bottomframe, text ="B", fg="gray", bg="blue", command = blueButtonCallBack)
-W = Tkinter.Button(bottomframe, text ="W", fg="gray", bg="white", command = whiteButtonCallBack)
+def buttonInit(text, bg, command):
+    return Tkinter.Button(buttonFrame, text =text, fg="snow", bg=bg, height=1, width=6, command=command)
+
+O = buttonInit("OFF", buttonColor, offButtonCallBack)
+R = buttonInit("RED", buttonColor, redButtonCallBack)
+G = buttonInit("GREEN", buttonColor, greenButtonCallBack)
+B = buttonInit("BLUE", buttonColor, blueButtonCallBack)
+W = buttonInit("WHITE", buttonColor, whiteButtonCallBack)
+ledButtons = [O, R, G, B, W]
 
 # Set font
-font = tkFont.Font(family='Times', size=24, weight='bold')
-O['font'] = font
-R['font'] = font
-G['font'] = font
-B['font'] = font
-W['font'] = font
+buttonFont = tkFont.Font(family='Arial', size=12, weight='bold')
+for button in ledButtons:
+    button['font'] = buttonFont
 
-# Arrange our controls
-ledStaticLabel.pack(side = LEFT)
-ledStatusLabel.pack(side = LEFT)
-tempStaticLabel.pack(side = LEFT)
-tempStatusLabel.pack(side = LEFT)
-humidStaticLabel.pack(side = LEFT)
-humidStatusLabel.pack(side = LEFT)
-versionStaticLabel.pack(side = LEFT)
-versionStatusLabel.pack(side = LEFT)
-O.pack(side = LEFT)
-R.pack(side = LEFT)
-G.pack(side = LEFT)
-B.pack(side = LEFT)
-W.pack(side = LEFT)
+buttonPadX = 5
+for button in ledButtons:
+    button.pack(side=LEFT, padx=buttonPadX)
+
+# NOTE: If you want to test the GUI layout without running the AWS code comment these lines in
+#window.mainloop()
+#exit(0)
 
 #######################################################################################################################
 #
@@ -225,7 +290,7 @@
     print("+++++++++++++++++++++\n\n")
 
     # Send payload to our status
-    setStatus(colorDict[reportedColor], reportedTemp, reportedHumid, reportedVersion)
+    setStatus(reportedColor, reportedTemp, reportedHumid, reportedVersion)
 
 getTimerAlive = TRUE
 def customShadowTimer_Get():
@@ -425,7 +490,8 @@
 # Delete shadow JSON doc
 #AIT.shadowDelete(customShadowCallback_Delete, 5)
 
-getTimer = Timer(3.0, customShadowTimer_Get, ())
+# NOTE: We make this slightly slower than the target loop (to prevent 'stale data')
+getTimer = Timer(3.5, customShadowTimer_Get, ())
 getTimer.start()
 
 # GUI loop (loops until closed)
Binary file PythonGUI/assets/ATT_Icon.ico has changed
Binary file PythonGUI/assets/LEDBlue.png has changed
Binary file PythonGUI/assets/LEDGreen.png has changed
Binary file PythonGUI/assets/LEDOff.png has changed
Binary file PythonGUI/assets/LEDRed.png has changed
Binary file PythonGUI/assets/LEDWhite.png has changed
Binary file PythonGUI/assets/attLogo.png has changed
Binary file PythonGUI/assets/awsLogo.png has changed
Binary file PythonGUI/assets/startKitBoard.png has changed
Binary file PythonGUI/assets/starterKitBox.png has changed
--- a/README.md	Fri Dec 16 18:04:39 2016 +0000
+++ b/README.md	Mon Dec 19 20:52:28 2016 +0000
@@ -102,25 +102,25 @@
    through the "Python AWS IoT Tutorial" to the point where you've installed Python 2.7.11 and the libraries
    required to run the script (paho-mqtt, AWSIoTPythonSDK).
 
-
+2) Copy the mbed project folder "PythonGUI" onto your PC somewhere. "C:/Temp/PythonGUI" for example.
 
-2a) Option a (default) - Use an mqtt_config.txt file:
+3a) Option a (default) - Use an mqtt_config.txt file:
    a) Use the same mqtt_config.txt file from MBED section above.
    b) Place the file where Python looks for it:
    AWS_MQTT_CONFIG_FILENAME     = "C:/Temp/certs/mqtt_config.txt"
 
-2b) Option b - Hard code the MQTT config:
+3b) Option b - Hard code the MQTT config:
    a) In the ATT_AWS_IoT_Demo_GUI.py script search for the "AWS IoT Config Parameters" and update them so they
       match the same 'thing' parameters as the mbed project.
 
    b) In the Python file change the following variable to TRUE:
    hardCodeMQTT = True
 
-3) Place your 'thing' certificates into file locations where the Python looks for them.  For example:
+4) Place your 'thing' certificates into file locations where the Python looks for them.  For example:
    AWS_IOT_ROOT_CA_FILENAME     = "C:/Temp/certs/rootCA-certificate.crt"
    AWS_IOT_PRIVATE_KEY_FILENAME = "C:/Temp/certs/private.pem.key"
    AWS_IOT_CERTIFICATE_FILENAME = "C:/Temp/certs/certificate.pem.crt"
-
+   
 Once all this is setup you should be able to:
 1) See the FRDM board start up and connect to Amazon and then create a 'thing' shadow (if there is none).
 2) See the FRDM board get the shadow LED color.