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 tweet_year(data): generated_this_week, generated_this_month, generated_this_year, total_generation = compute_generation_data(data) message = "This years @SolarCity Production was %s! %s generated since install :) #gosolar #bot" % \ (show_with_units(generated_this_year), show_with_units(total_generation)) if DEBUG_MODE: print "Would tweet:\n%s" % message log.debug("DEBUG mode, not tweeting: %s", message) else: tweet_string(message=message, log=log, media=random.choice(SOLAR_IMAGES))
def tweet_month(data): generated_this_week, generated_this_month, generated_this_year, total_generation = compute_generation_data( data) message = "This months @SolarCity Production was %s. %s generated in the last 365 days. #gosolar #bot" % \ (show_with_units(generated_this_month), show_with_units(generated_this_year)) if DEBUG_MODE: print("Would tweet:\n%s" % message) log.debug("DEBUG mode, not tweeting: %s", message) else: tweet_string(message=message, log=log, media=solar_image())
def tweet_down(): daysdown = (datetime.datetime.now() - datetime.datetime(2019, 8, 27)).days message = "@Tesla Solar system (17.6kW) was taken offline by @Tesla on 8/29/19, %d days ago. " \ "No repair possible for months." % daysdown if DEBUG_MODE: print("Would tweet:\n%s" % message) log.debug("DEBUG mode, not tweeting: %s", message) else: media = random.choice(SOLAR_IMAGES) log.debug("Using media: %s", media) tweet_string(message=message, log=log, media=media)
def tweet_major_mileage(miles): m = "{:,}".format(miles) a = random.choice(["an amazing", "an awesome", "a fantastic", "a wonderful"]) message = "Just passed %s miles on my Model S! It's been %s experience. " \ "#Tesla @TeslaMotors @Teslarati #bot" % (m, a) pic = random.choice(get_pics()) if DEBUG_MODE: print "Would tweet:\n%s with pic: %s" % (message, pic) logT.debug("DEBUG mode, not tweeting: %s with pic: %s", message, pic) else: logT.info("Tweeting: %s with pic: %s", message, pic) tweet_string(message=message, log=logT, media=pic)
def tweet_year(data): generated_this_week, generated_this_month, generated_this_year, total_generation = compute_generation_data( data) message = "This years @SolarCity Production was %s! %s generated since install :) #gosolar #bot" % \ (show_with_units(generated_this_year), show_with_units(total_generation)) if DEBUG_MODE: print("Would tweet:\n%s" % message) log.debug("DEBUG mode, not tweeting: %s", message) else: tweet_string(message=message, log=log, media=random.choice(SOLAR_IMAGES))
def check_current_firmware_version(c, data): v = None changed = False try: v = c.vehicles[0].data_request("vehicle_state")["car_version"].split( " ")[0] logT.debug("Found firmware version %s", v) except: logT.warning("Problems getting firmware version") t = datetime.date.today() ts = t.strftime("%Y%m%d") if "firmware" in data: if data["firmware"]["version"] != v: # TODO: Log new one found data["firmware"]["version"] = v data["firmware"]["date_detected"] = ts changed = True else: last_date = time.strptime(data["firmware"]["date_detected"], "%Y%m%d") last_date = datetime.date.fromtimestamp(time.mktime(last_date)) time_since = (datetime.date.today() - last_date).days try: firmware_date = time.strptime(v[:7] + ".6", "%Y.%W.%w") except: return changed firmware_age = ( datetime.date.today() - datetime.date.fromtimestamp(time.mktime(firmware_date))).days message = "My 2018 S75D is running firmware version %s. " \ "Firmware is ~%d days old. " \ "%d days since last update #bot" % (v, firmware_age, time_since) pic = random.choice(VERSION_IMAGES) if DEBUG_MODE: print("Would tweet:\n%s with pic: %s" % (message, pic)) logT.debug("DEBUG mode, not tweeting: %s with pic: %s", message, pic) else: logT.info("Tweeting: %s with pic: %s", message, pic) tweet_string(message=message, log=logT, media=pic) else: data["firmware"] = {} data["firmware"]["version"] = v data["firmware"]["date_detected"] = ts changed = True return changed
def tweet_major_mileage(miles, get_tweet=False): m = "{:,}".format(miles) a = random.choice( ["an amazing", "an awesome", "a fantastic", "a wonderful"]) message = "Just passed %s miles on my Model S 75D! It's been %s experience. " \ "#Tesla @TeslaMotors @Teslarati #bot" % (m, a) pic = random.choice(get_pics()) if DEBUG_MODE: print("Would tweet:\n%s with pic: %s" % (message, pic)) logT.debug("DEBUG mode, not tweeting: %s with pic: %s", message, pic) else: logT.info("Tweeting: %s with pic: %s", message, pic) if get_tweet: return message, pic else: tweet_string(message=message, log=logT, media=pic)
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 tweet_production(daylight_hours, cloud_cover, production, special): if special == "high": extra = "A new high record :) " elif special == "low": extra = ":( A new low " else: extra = "" if daylight_hours > 0.0: message = "Todays @SolarCity Production: %s with %.1f hrs of daylight and %d%% cloud cover. %s" \ "#gosolar #bot" % \ (show_with_units(production), daylight_hours, cloud_cover, extra) else: message = "Todays @SolarCity Production: %s (daylight/cloud cover not reported) %s" \ "#gosolar #bot" % \ (show_with_units(production), extra) if DEBUG_MODE: print("Would tweet:\n%s" % message) log.debug("DEBUG mode, not tweeting: %s", message) else: media = solar_image() log.debug("Using media: %s", media) tweet_string(message=message, log=log, media=media)
def tweet_production(daylight_hours, cloud_cover, production, special): if special == "high": extra = "A new high record :) " elif special == "low": extra = ":( A new low " else: extra = "" if daylight_hours > 0.0: message = "Todays @SolarCity Production: %s with %.1f hrs of daylight and %d%% cloud cover. %s" \ "#gosolar #bot" % \ (show_with_units(production), daylight_hours, cloud_cover, extra) else: message = "Todays @SolarCity Production: %s (daylight/cloud cover not reported) %s" \ "#gosolar #bot" % \ (show_with_units(production), extra) if DEBUG_MODE: print "Would tweet:\n%s" % message log.debug("DEBUG mode, not tweeting: %s", message) else: media = random.choice(SOLAR_IMAGES) log.debug("Using media: %s", media) tweet_string(message=message, log=log, media=media)
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 ---")
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 ---")