Compare commits

...

7 Commits

Author SHA1 Message Date
Ian Adam Naval
f4caad52ff Convert to standard logging library 2015-09-14 23:38:51 -04:00
Ian Adam Naval
40a9e0f5f7 Move email notification to config file 2015-09-14 23:26:13 -04:00
Ian Adam Naval
b26802003d Merge branch 'ifttt' 2015-09-14 22:52:05 -04:00
Ian Adam Naval
daef848cc0 Merge branch 'gitignore' 2015-09-14 22:51:06 -04:00
15de7719bf Add a gitignore 2015-09-14 22:40:18 -04:00
91c67d2b5c The previous commit message was useless 2015-09-14 22:39:06 -04:00
b7a58675c6 This is a useless commit message 2015-09-14 22:38:36 -04:00
2 changed files with 46 additions and 25 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
laundry_notifier/laundry_notifier.conf

View File

@ -1,20 +1,16 @@
import time
import datetime
import smtplib
import configparser
import logging
import math
from email.mime.text import MIMEText
import smtplib
import time
from datetime import datetime
from email.mime.text import MIMEText
import requests
from microstacknode.hardware.accelerometer.mma8452q import MMA8452Q
EMAIL_USERNAME = 'noreply@ianonavy.com'
EMAIL_PASSWORD = 'S2PENjQbO6=cHgchw@CXs.bJ'
RECIPIENT_EMAILS = [
'ianonavy@gmail.com',
'dmurvihill@gmail.com',
'5038304363@tmomail.net'
]
RECIPIENT_EMAILS = ['ianonavy@gmail.com']
ALERT_EMAIL_TEXT = """Hi,
Your laundry is done. Or maybe your roomate's. I don't know.
@ -27,6 +23,8 @@ INTERVAL = 0.005 # seconds
WINDOW_SIZE = 1000 # intervals
THRESHOLD = 0.025 # G's
MAX_EMAIL_FREQUENCY = 60 # seconds
MAX_NOTIFICATION_FREQUENCY = 60 # seconds
CONFIG_FILE_PATH = '/home/pi/laundry-notifier/laundry_notifier/laundry_notifier.conf'
def average(s):
@ -41,8 +39,8 @@ def stdev(s):
return math.sqrt(average(list(variance)))
def notify_user(recipient_email_address):
print("Alerting " + recipient_email_address)
def notify_user(username, password, recipient_email_address):
logging.info("Alerting " + recipient_email_address)
msg = MIMEText(ALERT_EMAIL_TEXT)
@ -53,8 +51,6 @@ def notify_user(recipient_email_address):
msg['To'] = recipient_email_address
# Send the message via our own SMTP server.
username = EMAIL_USERNAME
password = EMAIL_PASSWORD
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username, password)
@ -71,21 +67,37 @@ def enqueue(sliding_window, item):
def amplitude_stdev(sliding_window):
standard_deviations = {}
for key in ('x', 'y', 'z'):
values = [instance[key] for instance in sliding_window]
values = [measurement[key] for measurement in sliding_window]
standard_deviations[key] = stdev(values)
return standard_deviations
def send_emails(last_email_sent_at):
print((datetime.now() - last_email_sent_at).seconds) # for debugging
# limit frequency of emails
if (datetime.now() - last_email_sent_at).seconds > MAX_EMAIL_FREQUENCY:
def send_notifications(last_notification_sent_at, iftttkey):
seconds_since_last_notification = \
(datetime.now() - last_notification_sent_at).seconds
logging.info("Sending notification after %ds" % seconds_since_last_notification)
# limit frequency of notifications
if seconds_since_last_notification > MAX_NOTIFICATION_FREQUENCY:
[notify_user(email) for email in RECIPIENT_EMAILS]
# Notify if this, then that
requests.get(
'https://maker.ifttt.com/trigger/laundry_done/with/key/%s'
% iftttkey)
return datetime.now()
return last_email_sent_at
return last_notification_sent_at
def main():
LOG_FORMAT = '%(asctime)-15s %(message)s'
logging.basicConfig(format=LOG_FORMAT)
logging.getLogger().setLevel(logging.INFO)
logging.info('Started laundry notifier')
config = configparser.ConfigParser()
config.read(CONFIG_FILE_PATH)
notifications_section = config['notifications']
iftttkey = notifications_section['ifttt_key']
email_username = notifications_section['email_username']
email_password = notifications_section['email_password']
with MMA8452Q() as accelerometer:
# Configure accelerometer
accelerometer.standby()
@ -97,20 +109,27 @@ def main():
sliding_window = []
dryer_state = 'off'
last_email_sent_at = datetime(1970, 1, 1, 0, 0, 0)
last_notification_sent_at = datetime(1970, 1, 1, 0, 0, 0)
while True:
g_values = accelerometer.get_xyz()
enqueue(sliding_window, g_values)
sliding_stdev = amplitude_stdev(sliding_window)
print(sliding_stdev, dryer_state, len(sliding_window))
# don't send emails right at the beginning
if g_values:
if sliding_stdev['x'] < THRESHOLD:
# Notify recipients on state transitions from 'on' to 'off'
if dryer_state == 'on':
last_email_sent_at = send_emails(last_email_sent_at)
logging.info('Dryer turned off; sliding stdev is %f' % sliding_stdev['x'])
last_notification_sent_at = send_notifications(
last_notification_sent_at,
email_username,
email_password,
iftttkey)
dryer_state = 'off'
else:
# Log state transitions from 'off' to 'on'
if dryer_state == 'off':
logging.info('Dryer turned on; sliding stdev is %f' % sliding_stdev['x'])
dryer_state = 'on'
time.sleep(INTERVAL)