Merge pull request #1129 from jimbobbennett/master

Update code for PyPortal IoT Plant Monitor
This commit is contained in:
Brent Rubell 2020-06-16 13:26:58 -04:00 committed by GitHub
commit 6d6d4bfd39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 14 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ Hue_Controller/secrets.h
*.DS_Store
CircuitPython_Logger/secrets\.py
.python-version
__pycache__

View file

@ -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
# 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

View file

@ -13,7 +13,7 @@ main_font = cwd+"/fonts/EarthHeart-26.bdf"
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.
"""
@ -76,9 +76,9 @@ class Azure_GFX(displayio.Group):
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

View file

@ -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
@ -31,18 +38,39 @@ esp32_ready = DigitalInOut(board.ESP_BUSY)
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()
print("WiFi connected!")
# Time setup, needed to authenticate with Azure IoT Central
ntp = NTP(esp)
while not ntp.valid_time:
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:
@ -52,15 +80,27 @@ while True:
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()
device.reconnect()
continue
time.sleep(60)
# Sleep for 10 minutes before getting the next value
time.sleep(600)

BIN
PyPortal_Azure_Plant_Monitor/images/azure_splash.bmp Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 76 KiB