Merge pull request #1129 from jimbobbennett/master
Update code for PyPortal IoT Plant Monitor
This commit is contained in:
commit
6d6d4bfd39
5 changed files with 55 additions and 14 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,3 +4,4 @@ Hue_Controller/secrets.h
|
|||
*.DS_Store
|
||||
CircuitPython_Logger/secrets\.py
|
||||
.python-version
|
||||
__pycache__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
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 |
Loading…
Reference in a new issue