Skip to content

Instantly share code, notes, and snippets.

@tamalw
Created September 11, 2018 00:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tamalw/c336d0709468cab00c45328431c54f1e to your computer and use it in GitHub Desktop.
Save tamalw/c336d0709468cab00c45328431c54f1e to your computer and use it in GitHub Desktop.
from emu import *
from datetime import datetime, date, timedelta
emu_tty_filename = 'tty.usbmodem1411'
class EmuWrangler(object):
rates = {
'Summer' : {
'Peak' : (47334, 5),
'Partial-Peak' : (25994, 5),
'Off-Peak' : (12753, 5)
},
'Winter' : {
'Peak' : (32987, 5),
'Partial-Peak' : (20417, 5),
'Off-Peak' : (13046, 5)
}
}
yesterday = timedelta(days=-1)
def __init__(self, d):
self.date = d.date()
self.datetime = d
def weekend(self):
return self.date.weekday() >= 5
def season(self):
if 5 <= self.date.month <= 10:
return 'Summer'
else:
return 'Winter'
def new_years_day(self, d=False):
if d:
return d.month == 1 and d.day == 1
else:
return self.date.month == 1 and self.date.day == 1
def presidents_day(self, d=False):
# Third Monday in Feburary
if d:
return d.month == 2 and d.weekday() == 0 and (15 <= d.day <= 21)
else:
return self.date.month == 2 and self.date.weekday() == 0 and (15 <= self.date.day <= 21)
def memorial_day(self, d=False):
# Last Monday in May
if d:
return d.month == 5 and d.weekday() == 0 and d.day >= 25
else:
return self.date.month == 5 and self.date.weekday() == 0 and self.date.day >= 25
def independence_day(self, d=False):
if d:
return d.month == 7 and d.day == 4
else:
return self.date.month == 7 and self.date.day == 4
def labor_day(self, d=False):
# First Monday in September
if d:
return d.month == 9 and d.weekday() == 0 and d.day <= 7
else:
return self.date.month == 9 and self.date.weekday() == 0 and self.date.day <= 7
def veterans_day(self, d=False):
if d:
return d.month == 11 and d.day == 11
else:
return self.date.month == 11 and self.date.day == 11
def thanksgiving_day(self, d=False):
# Third Thursday in November
if d:
return d.month == 11 and d.weekday() == 3 and (15 <= d.day <= 21)
else:
return self.date.month == 11 and self.date.weekday() == 3 and (15 <= self.date.day <= 21)
def christmas_day(self, d=False):
if d:
return d.month == 12 and d.day == 25
else:
return self.date.month == 12 and self.date.day == 25
def holiday(self, date_arg=False):
if date_arg:
d = date_arg
else:
d = self.date
# New Years, Independence, Veterans, Christmas could be Sunday
if self.new_years_day(d):
return "New Year's Day"
elif d.weekday() == 0 and self.new_years_day(d+self.yesterday):
return "New Year's Day (observed)"
elif self.presidents_day(d):
return "President's Day"
elif self.memorial_day(d):
return "Memorial Day"
elif self.independence_day(d):
return "Independence Day"
elif d.weekday() == 0 and self.independence_day(d+self.yesterday):
return "Independence Day (observed)"
elif self.labor_day(d):
return "Labor Day"
elif self.veterans_day(d):
return "Veteran's Day"
elif d.weekday() == 0 and self.veterans_day(d+self.yesterday):
return "Veteran's Day (observed)"
elif self.thanksgiving_day(d):
return "Thanksgiving Day"
elif self.christmas_day(d):
return "Christmas Day"
elif d.weekday() == 0 and self.christmas_day(d+self.yesterday):
return "Christmas Day (observed)"
else:
return False
def dst_adjustment(self, date_arg=False):
if date_arg:
d = date_arg
else:
d = self.date
# second_sunday_in_march
for i in range(8,14):
a_date = date(d.year, 3, i)
if a_date.weekday() == 6:
second_sunday_in_march = a_date
break
# first_sunday_in_april
for i in range(1,7):
a_date = date(d.year, 4, i)
if a_date.weekday() == 6:
first_sunday_in_april = a_date
break
# last_sunday_in_october
for i in range(25,31):
a_date = date(d.year, 10, i)
if a_date.weekday() == 6:
last_sunday_in_october = a_date
break
# first_sunday_in_november
for i in range(1,7):
a_date = date(d.year, 11, i)
if a_date.weekday() == 6:
first_sunday_in_november = a_date
break
# I'm pretty sure the time change happens early in the morning, so I am excluding the last date.
if second_sunday_in_march <= d < first_sunday_in_april:
return timedelta(hours=-1)
elif last_sunday_in_october <= d < first_sunday_in_november:
return timedelta(hours=-1)
else:
return timedelta(hours=0)
def rate_category_weekend(self):
adj_hour = (self.datetime+self.dst_adjustment()).hour
if 15 <= adj_hour <= 18: # 3 PM through 6 PM
return 'Peak'
else:
return 'Off-Peak'
def rate_category_weekday(self):
adj_hour = (self.datetime+self.dst_adjustment()).hour
if 14 <= adj_hour <= 20: # 3 PM through 8 PM
return 'Peak'
elif 7 <= adj_hour <= 22: # 7 AM through 10 PM
return 'Partial-Peak'
else:
return 'Off-Peak'
def rate_category(self):
if self.holiday() or self.weekend():
return self.rate_category_weekend()
else:
return self.rate_category_weekday()
def rate(self):
return self.rates[self.season()][self.rate_category()]
def hex_rate(self):
rate = self.rate()
price = rate[0]
trailing_digits = rate[1]
return (hex(price), trailing_digits)
e = emu(emu_tty_filename)
e.start_serial()
w = EmuWrangler(datetime.now())
rate = w.hex_rate()
price = str(rate[0])
trailing_digits = str(rate[1])
e.set_current_price(price, trailing_digits)
time.sleep(5)
e.stop_serial()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment