def solarcity_report(data, no_email=False, no_tweet=False): log.debug("Report on SolarCity Generation") generated_this_week, generated_this_month, generated_this_year, total_generation = compute_generation_data(data) message = "Hi there, below is the weekly SolarCity generation report:\n\n" message += "Total production this week: %s\n" % show_with_units(generated_this_week) message += "Total production in the last 30 days: %s\n" % show_with_units(generated_this_month) message += "Total production in the last 365 days: %s\n" % show_with_units(generated_this_year) message += "\nLifetime generation is %s.\n" % show_with_units(total_generation) message += "\nRegards,\n" message += "Teslaliving\nhttp://teslaliving.net" if no_email or DEBUG_MODE: print "Would email message:\n%s" % message else: log.debug(" email report") email(email=SOLARCITY_USER, message=message, subject="Weekly SolarCity Report") if not no_tweet: tweet_message = "%s generated last week with @SolarCity. " % show_with_units(generated_this_week) tweet_message += "%s generated in the last 30 days. #GoSolar #bot" % show_with_units(generated_this_month) if DEBUG_MODE: print "Would Tweet string:\n%s" % tweet_message else: tweet_string(message=tweet_message, log=log, media=random.choice(SOLAR_IMAGES))
def mail_exception(e): logT.exception("Exception encountered") message = "There was a problem during tesla updates:\n\n" message += e message += "\nPlease investigate." if DEBUG_MODE: raise Exception("email issues") else: email(email=TESLA_EMAIL, message=message, subject="Tesla script error")
def mail_exception(e): logT.exception("Exception encountered") message = "There was a problem during tesla updates:\n\n" message += e message += "\nPlease investigate." if DEBUG_MODE: raise else: email(email=TESLA_EMAIL, message=message, subject="Tesla script error")
def check_tesla_fields(c, data): data_changed = False new_fields = [] t = datetime.date.today() ts = t.strftime("%Y%m%d") if not "known_fields" in data: data["known_fields"] = {} data_changed = True vehicles = c.vehicles for v in vehicles: logT.debug(" Processing %s" % v["display_name"]) for i in v: if i not in data["known_fields"]: logT.debug(" found new field %s. Value: %s", i, v[i]) new_fields.append(i) data["known_fields"][i] = ts data_changed = True for s in [ "vehicle_state", "charge_state", "climate_state", "drive_state", "gui_settings" ]: logT.debug(" Checking %s" % s) d = v.data_request("%s" % s) for i in d: if i not in data["known_fields"]: logT.debug(" found new field %s. Value: %s", i, d[i]) new_fields.append(i) data["known_fields"][i] = ts data_changed = True if len(new_fields) > 0: m = "Found %s new Tesla API fields:\n" % "{:,}".format(len(new_fields)) for i in new_fields: m += "\t%s\n" % i m += "\nRegards,\nRob" email(email=TESLA_EMAIL, message=m, subject="New Tesla API fields detected") else: logT.debug(" No new API fields detected.") return data_changed, data
def check_tesla_fields(c, data): data_changed = False new_fields = [] t = datetime.date.today() ts = t.strftime("%Y%m%d") if not "known_fields" in data: data["known_fields"] = {} data_changed = True vehicles = c.vehicles for v in vehicles: logT.debug(" Processing %s" % v["display_name"]) for i in v: if i not in data["known_fields"]: logT.debug(" found new field %s. Value: %s", i, v[i]) new_fields.append(i) data["known_fields"][i] = ts data_changed = True for s in ["vehicle_state", "charge_state", "climate_state", "drive_state", "gui_settings"]: logT.debug(" Checking %s" % s) d = v.data_request("%s" % s) for i in d: if i not in data["known_fields"]: logT.debug(" found new field %s. Value: %s", i, d[i]) new_fields.append(i) data["known_fields"][i] = ts data_changed = True if len(new_fields) > 0: m = "Found %s new Tesla API fields:\n" % "{:,}".format(len(new_fields)) for i in new_fields: m += "\t%s\n" % i m += "\nRegards,\nRob" email(email=TESLA_EMAIL, message=m, subject="New Tesla API fields detected") else: logT.debug(" No new API fields detected.") return data_changed, data
def solarcity_report(data, no_email=False, no_tweet=False): log.debug("Report on SolarCity Generation") generated_this_week, generated_this_month, generated_this_year, total_generation = compute_generation_data( data) message = "Hi there, below is the weekly SolarCity generation report:\n\n" message += "Total production this week: %s\n" % show_with_units( generated_this_week) message += "Total production in the last 30 days: %s\n" % show_with_units( generated_this_month) message += "Total production in the last 365 days: %s\n" % show_with_units( generated_this_year) message += "\nLifetime generation is %s.\n" % show_with_units( total_generation) message += "\nRegards,\n" message += "Teslaliving\nhttp://teslaliving.net" if no_email or DEBUG_MODE: print("Would email message:\n%s" % message) else: log.debug(" email report") email(email=SOLARCITY_USER, message=message, subject="Weekly SolarCity Report") if not no_tweet: tweet_message = "%s generated last week with @SolarCity. " % show_with_units( generated_this_week) tweet_message += "%s generated in the last 30 days. #GoSolar #bot" % show_with_units( generated_this_month) if DEBUG_MODE: print("Would Tweet string:\n%s" % tweet_message) else: tweet_string(message=tweet_message, log=log, media=solar_image())
def main(): parser = argparse.ArgumentParser(description='Tesla Control') parser.add_argument('--status', help='Get car status', required=False, action='store_true') parser.add_argument( '--mileage', help='Check car mileage and tweet as it crosses 1,000 mile marks', required=False, action='store_true') parser.add_argument('--state', help='Record car state', required=False, action='store_true') parser.add_argument('--pluggedin', help='Check if car is plugged in', required=False, action='store_true') parser.add_argument('--dump', help='Dump all fields/data', required=False, action='store_true') parser.add_argument('--fields', help='Check for newly added API fields', required=False, action='store_true') parser.add_argument('--day', help='Show state data for given day', required=False, type=str) parser.add_argument('--yesterday', help='Report on yesterdays driving', required=False, action='store_true') parser.add_argument('--export', help='Export data', required=False, action='store_true') parser.add_argument('--report', help='Produce summary report', required=False, action='store_true') parser.add_argument('--garage', help='Trigger garage door (experimental)', required=False, action='store_true') parser.add_argument('--sunroof', help='Control sunroof (vent, open, close)', required=False, type=str) parser.add_argument('--mailtest', help='Test emailing', required=False, action='store_true') parser.add_argument('--chargecheck', help='Check if car is currently charging', required=False, action='store_true') parser.add_argument('--firmware', help='Check for new firmware versions', required=False, action='store_true') args = parser.parse_args() get_lock() logT.debug("--- tesla.py start ---") data = load_data() data_changed = False # Get a connection to the car and manage access token if 'token' in data: token = data['token'] else: token = None try: c = establish_connection(token) except: logT.debug("Problems establishing connection") c = establish_connection() if c.access_token: if not 'token' in data or data['token'] != c.access_token: data['token'] = c.access_token data_changed = True if args.status: # Dump current Tesla status try: print(dump_current_tesla_status(c)) except: logT.warning("Couldn't dump status this pass") elif args.dump: # Dump all of Tesla API state information to disk logT.debug("Dumping current Tesla state") t = datetime.date.today() ts = t.strftime("%Y%m%d") try: m = dump_current_tesla_status(c) open(os.path.join(DUMP_DIR, "tesla_state_%s.txt" % ts), "w").write(m) except: logT.warning("Couldn't get dump this pass") elif args.fields: # Check for new Tesla API fields and report if any found logT.debug("Checking Tesla API fields") try: data_changed, data = check_tesla_fields(c, data) except: logT.warning("Couldn't check fields this pass") elif args.mileage: # Tweet mileage as it crosses 1,000 mile marks try: m = get_odometer(c, CAR_NAME) except: logT.warning("Couldn't get odometer this pass") return if "mileage_tweet" not in data: data["mileage_tweet"] = 0 if int(m / 1000) > int(data["mileage_tweet"] / 1000): tweet_major_mileage(int(m / 1000) * 1000) data["mileage_tweet"] = m data_changed = True elif args.chargecheck: # Check for charges so we can correctly report daily efficiency try: m = is_charging(c, CAR_NAME) except: logT.warning("Couldn't get charge state this pass") return if not data["charging"] and m: logT.debug(" State change, not charging to charging") data["charging"] = True data["day_charges"] += 1 data_changed = True elif data["charging"] and m is False: logT.debug(" State change from charging to not charging") data["charging"] = False data_changed = True elif args.state: # Save current Tesla state information logT.debug("Saving Tesla state") retries = 3 s = None while retries > 0: try: s = get_current_state(c, CAR_NAME) break except: retries -= 1 if retries > 0: logT.exception( " Problem getting current state, sleeping and trying again" ) time.sleep(30) if s is None: logT.error(" Could not fetch current state") raise Exception("Couldnt fetch Tesla state") logT.debug(" got current state") t = datetime.date.today() ts = t.strftime("%Y%m%d") hour = datetime.datetime.now().hour if hour < 12: ampm = "am" else: ampm = "pm" data["daily_state_%s" % ampm][ts] = s logT.debug(" added to database") data_changed = True elif args.day: # Show Tesla state information from a given day ts = args.day raw = "" if ts in data["daily_state_am"]: print("Data for %s am:" % ts) for i in ("odometer", "soc", "ideal_range", "rated_range", "estimated_range", "charge_energy_added", "charge_miles_added_ideal", "charge_miles_added_rated"): print("%s: %s" % (i, data["daily_state_am"][ts][i])) raw += "%s\t" % data["daily_state_am"][ts][i] print("\nRaw: %s" % raw) elif args.report: # Show total and average energy added total_energy_added = 0 for ts in data["daily_state_am"]: if ts < "20151030": continue total_energy_added += data["daily_state_am"][ts][ "charge_energy_added"] print("Total Energy Added: %s kW" % "{:,.2f}".format(total_energy_added)) print("Average Energy Added: %s kW" % "{:,.2f}".format( (total_energy_added / len(data["daily_state_am"])))) elif args.export: # Export all saved Tesla state information for ts in sorted(data["daily_state_am"]): if ts < "20151030": continue print("%s," % ts, end=' ') for i in ("odometer", "soc", "ideal_range", "rated_range", "estimated_range", "charge_energy_added", "charge_miles_added_ideal", "charge_miles_added_rated"): print("%s," % data["daily_state_am"][ts][i], end=' ') print("") elif args.pluggedin: # Check if the Tesla is plugged in and alert if not logT.debug("Checking if Tesla is plugged in") if not is_plugged_in(c, CAR_NAME): s = get_current_state(c, CAR_NAME, include_temps=False) message = "Your car is not plugged in.\n\n" message += "Current battery level is %d%%. (%d estimated miles)" % ( s["soc"], int(s["estimated_range"])) message += "\n\nRegards,\nRob" email(email=TESLA_EMAIL, message=message, subject="Your Tesla isn't plugged in") logT.debug(" Not plugged in. Emailed notice.") else: logT.debug(" Its plugged in.") elif args.mailtest: # Test emailing logT.debug("Testing email function") message = "Email test from tool.\n\n" message += "If you're getting this its working." message += "\n\nRegards,\nRob" try: email(email=TESLA_EMAIL, message=message, subject="Tesla Email Test") logT.debug(" Successfully sent the mail.") print("Mail send passed.") except: logT.exception("Problem trying to send mail") print("Mail send failed, see log.") elif args.yesterday: m, pic = report_yesterday(data) data["day_charges"] = 0 data_changed = True if m: if DEBUG_MODE: print("Would tweet:\n%s with pic: %s" % (m, pic)) logT.debug("DEBUG mode, not tweeting: %s with pic: %s", m, pic) else: logT.info("Tweeting: %s with pic: %s", m, pic) tweet_string(message=m, log=logT, media=pic) else: logT.debug("No update, skipping yesterday report") elif args.garage: # Open garage door (experimental as I dont have an AP car) trigger_garage_door(c, CAR_NAME) elif args.firmware: # Check firmware version for a change data_changed = check_current_firmware_version(c, data) elif args.sunroof: # Change sunroof state trigger_sunroof(c, CAR_NAME, args.sunroof) if data_changed: save_data(data) remove_lock() logT.debug("--- tesla.py end ---")
def main(): parser = argparse.ArgumentParser(description='Tesla Control') parser.add_argument('--status', help='Get car status', required=False, action='store_true') parser.add_argument('--mileage', help='Check car mileage and tweet as it crosses 1,000 mile marks', required=False, action='store_true') parser.add_argument('--state', help='Record car state', required=False, action='store_true') parser.add_argument('--pluggedin', help='Check if car is plugged in', required=False, action='store_true') parser.add_argument('--dump', help='Dump all fields/data', required=False, action='store_true') parser.add_argument('--fields', help='Check for newly added API fields', required=False, action='store_true') parser.add_argument('--day', help='Show state data for given day', required=False, type=str) parser.add_argument('--yesterday', help='Report on yesterdays driving', required=False, action='store_true') parser.add_argument('--export', help='Export data', required=False, action='store_true') parser.add_argument('--report', help='Produce summary report', required=False, action='store_true') parser.add_argument('--garage', help='Trigger garage door (experimental)', required=False, action='store_true') parser.add_argument('--sunroof', help='Control sunroof (vent, open, close)', required=False, type=str) parser.add_argument('--mailtest', help='Test emailing', required=False, action='store_true') args = parser.parse_args() get_lock() logT.debug("--- tesla.py start ---") data = load_data() data_changed = False # Get a connection to the car and manage access token if 'token' in data: token = data['token'] else: token = None try: c = establish_connection(token) except: logT.debug("Problems establishing connection") c = establish_connection() if c.access_token: if not 'token' in data or data['token'] != c.access_token: data['token'] = c.access_token data_changed = True if args.status: # Dump current Tesla status print dump_current_tesla_status(c) elif args.dump: # Dump all of Tesla API state information to disk logT.debug("Dumping current Tesla state") t = datetime.date.today() ts = t.strftime("%Y%m%d") m = dump_current_tesla_status(c) open(os.path.join(DUMP_DIR, "tesla_state_%s.txt" % ts), "w").write(m) elif args.fields: # Check for new Tesla API fields and report if any found logT.debug("Checking Tesla API fields") data_changed, data = check_tesla_fields(c, data) elif args.mileage: # Tweet mileage as it crosses 1,000 mile marks m = get_odometer(c, CAR_NAME) if "mileage_tweet" not in data: data["mileage_tweet"] = 0 if int(m / 1000) > int(data["mileage_tweet"] / 1000): tweet_major_mileage(int(m / 1000) * 1000) data["mileage_tweet"] = m data_changed = True elif args.state: # Save current Tesla state information logT.debug("Saving Tesla state") retries = 3 s = None while retries > 0: try: s = get_current_state(c, CAR_NAME) break except: retries -= 1 if retries > 0: logT.exception(" Problem getting current state, sleeping and trying again") time.sleep(30) if s is None: logT.error(" Could not fetch current state") raise Exception("Couldnt fetch Tesla state") logT.debug(" got current state") t = datetime.date.today() ts = t.strftime("%Y%m%d") hour = datetime.datetime.now().hour if hour < 12: ampm = "am" else: ampm = "pm" data["daily_state_%s" % ampm][ts] = s logT.debug(" added to database") data_changed = True elif args.day: # Show Tesla state information from a given day ts = args.day raw = "" if ts in data["daily_state_am"]: print "Data for %s am:" % ts for i in ("odometer", "soc", "ideal_range", "rated_range", "estimated_range", "charge_energy_added", "charge_miles_added_ideal", "charge_miles_added_rated"): print "%s: %s" % (i, data["daily_state_am"][ts][i]) raw += "%s\t" % data["daily_state_am"][ts][i] print "\nRaw: %s" % raw elif args.report: # Show total and average energy added total_energy_added = 0 for ts in data["daily_state_am"]: if ts < "20151030": continue total_energy_added += data["daily_state_am"][ts]["charge_energy_added"] print "Total Energy Added: %s kW" % "{:,.2f}".format(total_energy_added) print "Average Energy Added: %s kW" % "{:,.2f}".format((total_energy_added / len(data["daily_state_am"]))) elif args.export: # Export all saved Tesla state information for ts in sorted(data["daily_state_am"]): if ts < "20151030": continue print "%s," % ts, for i in ("odometer", "soc", "ideal_range", "rated_range", "estimated_range", "charge_energy_added", "charge_miles_added_ideal", "charge_miles_added_rated"): print "%s," % data["daily_state_am"][ts][i], print "" elif args.pluggedin: # Check if the Tesla is plugged in and alert if not logT.debug("Checking if Tesla is plugged in") if not is_plugged_in(c, CAR_NAME): s = get_current_state(c, CAR_NAME, include_temps=False) message = "Your car is not plugged in.\n\n" message += "Current battery level is %d%%. (%d estimated miles)" % (s["soc"], int(s["estimated_range"])) message += "\n\nRegards,\nRob" email(email=TESLA_EMAIL, message=message, subject="Your Tesla isn't plugged in") logT.debug(" Not plugged in. Emailed notice.") else: logT.debug(" Its plugged in.") elif args.mailtest: # Test emailing logT.debug("Testing email function") message = "Email test from tool.\n\n" message += "If you're getting this its working." message += "\n\nRegards,\nRob" try: email(email=TESLA_EMAIL, message=message, subject="Tesla Email Test") logT.debug(" Successfully sent the mail.") print "Mail send passed." except: logT.exception("Problem trying to send mail") print "Mail send failed, see log." elif args.yesterday: m, pic = report_yesterday(data) if DEBUG_MODE: print "Would tweet:\n%s with pic: %s" % (m, pic) logT.debug("DEBUG mode, not tweeting: %s with pic: %s", m, pic) else: logT.info("Tweeting: %s with pic: %s", m, pic) tweet_string(message=m, log=logT, media=pic) elif args.garage: # Open garage door (experimental as I dont have an AP car) trigger_garage_door(c, CAR_NAME) elif args.sunroof: # Change sunroof state trigger_sunroof(c, CAR_NAME, args.sunroof) if data_changed: save_data(data) remove_lock() logT.debug("--- tesla.py end ---")
) print('<li><i>Note 2: Cloud/Daylight data <a href="http://forecast.io">Powered by Forecast</a> when ' \ 'SolarCity data missing.</i></li>') print( '<li><i>Note 3: System was degraded from 20170530 to 20170726. Up to 30 panels offline.</i></li>' ) print('</ul>') if data_changed: save_data(data) log.debug("--- solarcity.py end ---") if __name__ == '__main__': try: main() except SystemExit: pass except: log.exception("Exception encountered") message = "There was a problem during solarcity updates:\n\n" message += traceback.format_exc() message += "\nPlease investigate." if DEBUG_MODE: raise else: email(email=SOLARCITY_USER, message=message, subject="Solarcity Poll Error")
print '\nSign up for <a href="http://share.solarcity.com/teslaliving">SolarCity</a> and save on electric!' print '\nFollow <a href="https://twitter.com/teslaliving">@TeslaLiving</a>.' print '\n<ul>' print '<li><i>Note 1: Detailed generation tracking started 20150612.</i></li>' print '<li><i>Note 2: Cloud/Daylight data <a href="http://forecast.io">Powered by Forecast</a> when ' \ 'SolarCity data missing.</i></li>' print '</ul>' print '<a href="https://gratipay.com/teslaliving/"><img src="//img.shields.io/gratipay/teslaliving.svg"></a>' if data_changed: save_data(data) log.debug("--- solarcity.py end ---") if __name__ == '__main__': try: main() except SystemExit: pass except: log.exception("Exception encountered") message = "There was a problem during solarcity updates:\n\n" message += traceback.format_exc() message += "\nPlease investigate." if DEBUG_MODE: raise else: email(email=SOLARCITY_USER, message=message, subject="Solarcity Poll Error")
def main(): parser = argparse.ArgumentParser(description='Tesla Control') parser.add_argument('--status', help='Get car status', required=False, action='store_true') parser.add_argument('--mileage', help='Check car mileage and tweet as it crosses 1,000 mile marks', required=False, action='store_true') parser.add_argument('--state', help='Record car state', required=False, action='store_true') parser.add_argument('--pluggedin', help='Check if car is plugged in', required=False, action='store_true') parser.add_argument('--dump', help='Dump all fields/data', required=False, action='store_true') parser.add_argument('--fields', help='Check for newly added API fields', required=False, action='store_true') parser.add_argument('--day', help='Show state data for given day', required=False, type=str) parser.add_argument('--yesterday', help='Report on yesterdays driving', required=False, action='store_true') parser.add_argument('--export', help='Export data', required=False, action='store_true') parser.add_argument('--report', help='Produce summary report', required=False, action='store_true') parser.add_argument('--garage', help='Trigger garage door (experimental)', required=False, action='store_true') parser.add_argument('--sunroof', help='Control sunroof (vent, open, close)', required=False, type=str) args = parser.parse_args() # Make sure we only run one instance at a time blocked = True while blocked: fp = open('/tmp/tesla.lock', 'w') try: fcntl.flock(fp.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) blocked = False except: logT.debug("Someone else is running this tool right now. Sleeping") time.sleep(30) logT.debug("--- tesla.py start ---") data = load_data() data_changed = False # Get a connection to the car and manage access token if 'token' in data: token = data['token'] else: token = None try: c = establish_connection(token) except: logT.debug("Problems establishing connection") c = establish_connection() if c.access_token: if not 'token' in data or data['token'] != c.access_token: data['token'] = c.access_token data_changed = True if args.status: # Dump current Tesla status print dump_current_tesla_status(c) elif args.dump: # Dump all of Tesla API state information to disk logT.debug("Dumping current Tesla state") t = datetime.date.today() ts = t.strftime("%Y%m%d") m = dump_current_tesla_status(c) open(os.path.join(DUMP_DIR, "tesla_state_%s.txt" % ts), "w").write(m) elif args.fields: # Check for new Tesla API fields and report if any found logT.debug("Checking Tesla API fields") data_changed, data = check_tesla_fields(c, data) elif args.mileage: # Tweet mileage as it crosses 1,000 mile marks m = get_odometer(c, CAR_NAME) if "mileage_tweet" not in data: data["mileage_tweet"] = 0 if int(m / 1000) > int(data["mileage_tweet"] / 1000): tweet_major_mileage(int(m / 1000) * 1000) data["mileage_tweet"] = m data_changed = True elif args.state: # Save current Tesla state information logT.debug("Saving Tesla state") s = get_current_state(c, CAR_NAME) t = datetime.date.today() ts = t.strftime("%Y%m%d") hour = datetime.datetime.now().hour if hour < 12: ampm = "am" else: ampm = "pm" data["daily_state_%s" % ampm][ts] = s data_changed = True elif args.day: # Show Tesla state information from a given day ts = args.day if ts in data["daily_state_am"]: print "Data for %s am:" % ts for i in ("odometer", "soc", "ideal_range", "rated_range", "estimated_range", "charge_energy_added", "charge_miles_added_ideal", "charge_miles_added_rated"): print "%s: %s" % (i, data["daily_state_am"][ts][i]) elif args.report: # Show total and average energy added total_energy_added = 0 for ts in data["daily_state_am"]: if ts < "20151030": continue total_energy_added += data["daily_state_am"][ts]["charge_energy_added"] print "Total Energy Added: %s kW" % "{:,.2f}".format(total_energy_added) print "Average Energy Added: %s kW" % "{:,.2f}".format((total_energy_added / len(data["daily_state_am"]))) elif args.export: # Export all saved Tesla state information for ts in sorted(data["daily_state_am"]): if ts < "20151030": continue print "%s," % ts, for i in ("odometer", "soc", "ideal_range", "rated_range", "estimated_range", "charge_energy_added", "charge_miles_added_ideal", "charge_miles_added_rated"): print "%s," % data["daily_state_am"][ts][i], print "" elif args.pluggedin: # Check if the Tesla is plugged in and alert if not logT.debug("Checking if Tesla is plugged in") if not is_plugged_in(c, CAR_NAME): s = get_current_state(c, CAR_NAME, include_temps=False) message = "Your car is not plugged in.\n\n" message += "Current battery level is %d%%. (%d estimated miles)" % (s["soc"], int(s["estimated_range"])) message += "\n\nRegards,\nRob" email(email=TESLA_EMAIL, message=message, subject="Your Tesla isn't plugged in") elif args.yesterday: # Report on yesterdays mileage/efficiency t = datetime.date.today() today_ts = t.strftime("%Y%m%d") t = t + datetime.timedelta(days=-1) yesterday_ts = t.strftime("%Y%m%d") if today_ts not in data["daily_state_am"] or yesterday_ts not in data["daily_state_am"]: logT.debug("Skipping yesterday tweet due to missing items") else: miles_driven = data["daily_state_am"][today_ts]["odometer"] - data["daily_state_am"][yesterday_ts][ "odometer"] kw_used = data["daily_state_am"][today_ts]["charge_energy_added"] if miles_driven > 200: m = "Yesterday I drove my #Tesla %s miles on a road trip! " \ "@Teslamotors #bot" % ("{:,}".format(int(miles_driven))) elif miles_driven == 0: mileage = data["daily_state_am"][today_ts]["odometer"] today_ym = datetime.date.today() start_ym = datetime.date(2014, 4, 21) ownership_months = int((today_ym - start_ym).days / 30) m = "Yesterday my #Tesla had a day off. Current mileage is %s miles after %d months " \ "@Teslamotors #bot" % ("{:,}".format(int(mileage)), ownership_months) else: day = yesterday_ts time_value = time.mktime(time.strptime("%s2100" % day, "%Y%m%d%H%M")) w = get_daytime_weather_data(logT, time_value) m = "Yesterday I drove my #Tesla %s miles using %.1f kW with an effic. of %d Wh/mi. Avg temp %.1fF. " \ "@Teslamotors #bot" \ % ("{:,}".format(int(miles_driven)), kw_used, kw_used * 1000 / miles_driven, w["avg_temp"]) pic = random.choice(get_pics()) if DEBUG_MODE: print "Would tweet:\n%s with pic: %s" % (m, pic) logT.debug("DEBUG mode, not tweeting: %s with pic: %s", m, pic) else: logT.info("Tweeting: %s with pic: %s", m, pic) tweet_string(message=m, log=logT, media=pic) elif args.garage: # Open garage door (experimental as I dont have an AP car) trigger_garage_door(c, CAR_NAME) elif args.sunroof: # Change sunroof state trigger_sunroof(c, CAR_NAME, args.sunroof) if data_changed: save_data(data) logT.debug("--- tesla.py end ---")