Esempio n. 1
0
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))
Esempio n. 2
0
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")
Esempio n. 3
0
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")
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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())
Esempio n. 7
0
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 ---")
Esempio n. 8
0
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 ---")
Esempio n. 9
0
        )
        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")
Esempio n. 10
0
        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")
Esempio n. 11
0
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 ---")