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