Skip to content

Commit 6d6d4bf

Browse files
authored
Merge pull request adafruit#1129 from jimbobbennett/master
Update code for PyPortal IoT Plant Monitor
2 parents 6006bda + ffc3015 commit 6d6d4bf

File tree

5 files changed

+55
-14
lines changed

5 files changed

+55
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ Hue_Controller/secrets.h
44
*.DS_Store
55
CircuitPython_Logger/secrets\.py
66
.python-version
7+
__pycache__

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ confidence=
5252
# no Warning level messages displayed, use"--disable=all --enable=classes
5353
# --disable=W"
5454
# 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
55-
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
55+
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
5656

5757
# Enable the message, report, category or checker with the given id(s). You can
5858
# either give multiple identifier separated by comma (,) or put this option

PyPortal_Azure_Plant_Monitor/azure_gfx_helper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
data_font = cwd+"/fonts/Collegiate-50.bdf"
1414

1515
class Azure_GFX(displayio.Group):
16-
def __init__(self, is_celsius=True):
16+
def __init__(self, is_celsius):
1717
"""Creates an Azure_GFX object.
1818
:param bool is_celsius: Temperature displayed in Celsius.
1919
"""
@@ -76,9 +76,9 @@ def __init__(self, is_celsius=True):
7676
self.azure_status_text.y = 225
7777
self._text_group.append(self.azure_status_text)
7878

79+
def show_text(self):
7980
board.DISPLAY.show(self._text_group)
8081

81-
8282
def display_azure_status(self, status_text):
8383
"""Displays the system status on the PyPortal
8484
:param str status_text: Description of Azure IoT status

PyPortal_Azure_Plant_Monitor/code.py

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
"""
22
PyPortal Azure IoT Plant Monitor
33
====================================================
4-
Log plant vitals to Microsoft Azure IoT with
4+
Log plant vitals to Microsoft Azure IoT Central with
55
your PyPortal
66
7-
Author: Brent Rubell for Adafruit Industries, 2019
7+
Authors: Brent Rubell for Adafruit Industries, 2019
8+
: Jim Bennett for Microsoft, 2020
89
"""
910
import time
11+
import json
1012
import board
1113
import busio
1214
from digitalio import DigitalInOut
1315
from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager
16+
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
1417
import neopixel
15-
from adafruit_azureiot import IOT_Hub
18+
from adafruit_ntp import NTP
19+
from adafruit_azureiot import IoTCentralDevice
1620
from adafruit_seesaw.seesaw import Seesaw
1721

1822
# gfx helper
1923
import azure_gfx_helper
2024

25+
# init. graphics helper
26+
gfx = azure_gfx_helper.Azure_GFX(is_celsius=True)
27+
2128
# Get wifi details and more from a secrets.py file
2229
try:
2330
from secrets import secrets
@@ -31,18 +38,39 @@
3138
esp32_reset = DigitalInOut(board.ESP_RESET)
3239
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
3340
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
41+
42+
# Set up the WiFi manager with a status light to show the WiFi connection status
3443
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
3544
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
45+
print("WiFi connecting...")
46+
wifi.connect()
47+
print("WiFi connected!")
48+
49+
# Time setup, needed to authenticate with Azure IoT Central
50+
ntp = NTP(esp)
51+
while not ntp.valid_time:
52+
print("Failed to obtain time, retrying in 5 seconds...")
53+
time.sleep(5)
54+
ntp.set_time()
3655

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

41-
# Create an instance of the Azure IoT Hub
42-
hub = IOT_Hub(wifi, secrets['azure_iot_hub'], secrets['azure_iot_sas'], secrets['azure_device_id'])
60+
# Create an instance of the Azure IoT Central device
61+
device = IoTCentralDevice(
62+
socket,
63+
esp,
64+
secrets["id_scope"],
65+
secrets["device_id"],
66+
secrets["key"]
67+
)
4368

44-
# init. graphics helper
45-
gfx = azure_gfx_helper.Azure_GFX(False)
69+
# Connect to Azure IoT Central
70+
device.connect()
71+
72+
# Hide the splash screen and show the telemetry values
73+
gfx.show_text()
4674

4775
while True:
4876
try:
@@ -52,15 +80,27 @@
5280
temperature = ss.get_temp()
5381
# display soil sensor values on pyportal
5482
gfx.display_moisture(moisture_level)
55-
temperature = gfx.display_temp(temperature)
83+
gfx.display_temp(temperature)
84+
5685
print('Sending data to Azure')
5786
gfx.display_azure_status('Sending data...')
58-
hub.send_device_message(temperature)
59-
hub.send_device_message(moisture_level)
87+
88+
# send the temperature and moisture level to Azure
89+
message = {
90+
"Temperature": temperature,
91+
"MoistureLevel": moisture_level
92+
}
93+
device.send_telemetry(json.dumps(message))
94+
device.loop()
95+
6096
gfx.display_azure_status('Data sent!')
6197
print('Data sent!')
6298
except (ValueError, RuntimeError) as e:
6399
print("Failed to get data, retrying\n", e)
64100
wifi.reset()
101+
wifi.connect()
102+
device.reconnect()
65103
continue
66-
time.sleep(60)
104+
105+
# Sleep for 10 minutes before getting the next value
106+
time.sleep(600)

PyPortal_Azure_Plant_Monitor/images/azure_splash.bmp

100755100644
-149 KB
Binary file not shown.

0 commit comments

Comments
 (0)