Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update code for PyPortal IoT Plant Monitor #1129

Merged
merged 20 commits into from
Jun 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ Hue_Controller/secrets.h
*.DS_Store
CircuitPython_Logger/secrets\.py
.python-version
__pycache__
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ confidence=
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
disable=too-many-instance-attributes,len-as-condition,too-few-public-methods,anomalous-backslash-in-string,no-else-return,simplifiable-if-statement,too-many-arguments,duplicate-code,no-name-in-module,no-member,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,missing-docstring,invalid-name,bad-whitespace,consider-using-enumerate
disable=too-many-instance-attributes,len-as-condition,too-few-public-methods,anomalous-backslash-in-string,no-else-return,simplifiable-if-statement,too-many-arguments,duplicate-code,no-name-in-module,no-member,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,missing-docstring,invalid-name,bad-whitespace,consider-using-enumerate,unexpected-keyword-arg
brentru marked this conversation as resolved.
Show resolved Hide resolved

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
4 changes: 2 additions & 2 deletions PyPortal_Azure_Plant_Monitor/azure_gfx_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
data_font = cwd+"/fonts/Collegiate-50.bdf"

class Azure_GFX(displayio.Group):
def __init__(self, is_celsius=True):
def __init__(self, is_celsius):
"""Creates an Azure_GFX object.
:param bool is_celsius: Temperature displayed in Celsius.
"""
Expand Down Expand Up @@ -76,9 +76,9 @@ def __init__(self, is_celsius=True):
self.azure_status_text.y = 225
self._text_group.append(self.azure_status_text)

def show_text(self):
board.DISPLAY.show(self._text_group)


def display_azure_status(self, status_text):
"""Displays the system status on the PyPortal
:param str status_text: Description of Azure IoT status
Expand Down
62 changes: 51 additions & 11 deletions PyPortal_Azure_Plant_Monitor/code.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
"""
PyPortal Azure IoT Plant Monitor
====================================================
Log plant vitals to Microsoft Azure IoT with
Log plant vitals to Microsoft Azure IoT Central with
your PyPortal

Author: Brent Rubell for Adafruit Industries, 2019
Authors: Brent Rubell for Adafruit Industries, 2019
: Jim Bennett for Microsoft, 2020
"""
import time
import json
import board
import busio
from digitalio import DigitalInOut
from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import neopixel
from adafruit_azureiot import IOT_Hub
from adafruit_ntp import NTP
from adafruit_azureiot import IoTCentralDevice
from adafruit_seesaw.seesaw import Seesaw

# gfx helper
import azure_gfx_helper

# init. graphics helper
gfx = azure_gfx_helper.Azure_GFX(is_celsius=True)

# Get wifi details and more from a secrets.py file
try:
from secrets import secrets
Expand All @@ -31,18 +38,39 @@
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

# Set up the WiFi manager with a status light to show the WiFi connection status
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
print("WiFi connecting...")
wifi.connect()
jimbobbennett marked this conversation as resolved.
Show resolved Hide resolved
print("WiFi connected!")

# Time setup, needed to authenticate with Azure IoT Central
ntp = NTP(esp)
while not ntp.valid_time:
jimbobbennett marked this conversation as resolved.
Show resolved Hide resolved
print("Failed to obtain time, retrying in 5 seconds...")
time.sleep(5)
ntp.set_time()

# Soil Sensor Setup
i2c_bus = busio.I2C(board.SCL, board.SDA)
ss = Seesaw(i2c_bus, addr=0x36)

# Create an instance of the Azure IoT Hub
hub = IOT_Hub(wifi, secrets['azure_iot_hub'], secrets['azure_iot_sas'], secrets['azure_device_id'])
# Create an instance of the Azure IoT Central device
device = IoTCentralDevice(
socket,
esp,
secrets["id_scope"],
secrets["device_id"],
secrets["key"]
)

# init. graphics helper
gfx = azure_gfx_helper.Azure_GFX(False)
# Connect to Azure IoT Central
device.connect()

# Hide the splash screen and show the telemetry values
gfx.show_text()

while True:
try:
Expand All @@ -52,15 +80,27 @@
temperature = ss.get_temp()
# display soil sensor values on pyportal
gfx.display_moisture(moisture_level)
temperature = gfx.display_temp(temperature)
gfx.display_temp(temperature)

print('Sending data to Azure')
gfx.display_azure_status('Sending data...')
hub.send_device_message(temperature)
hub.send_device_message(moisture_level)

# send the temperature and moisture level to Azure
message = {
"Temperature": temperature,
"MoistureLevel": moisture_level
}
device.send_telemetry(json.dumps(message))
device.loop()

gfx.display_azure_status('Data sent!')
print('Data sent!')
except (ValueError, RuntimeError) as e:
print("Failed to get data, retrying\n", e)
wifi.reset()
wifi.connect()
brentru marked this conversation as resolved.
Show resolved Hide resolved
device.reconnect()
continue
time.sleep(60)

# Sleep for 10 minutes before getting the next value
time.sleep(600)
Binary file modified PyPortal_Azure_Plant_Monitor/images/azure_splash.bmp
100755 → 100644
Binary file not shown.