Plugin help

Posted on
Fri Jan 05, 2024 2:35 pm
mwoodage offline
User avatar
Posts: 174
Joined: Dec 19, 2014
Location: Devon UK

Re: Plugin help

Thanks Joe, that works!

Needed to transfer the credentials folder over as well, but it works,

Code: Select all
Last login: Fri Jan  5 20:30:38 on ttys000
martin@Martins-Mac-mini-2 Totota % python3 simple_client_example.py
Traceback (most recent call last):
  File "/Users/martin/Totota/simple_client_example.py", line 30, in <module>
    raise ValueError(
ValueError: Did you forget to set your username and password? Or supply the credentials file
martin@Martins-Mac-mini-2 Totota % python3 simple_client_example.py
Logging in...
Retrieving cars...
('Dashboard: odometer=4562.0 fuel_level=64 battery_level=75 fuel_range=260.0 '
 'battery_range=31.876 battery_range_with_ac=29.645 range=289.559 '
 'charging_status=plugged remaining_charge_time=None warning_lights=[]')
martin@Martins-Mac-mini-2 Totota %


Posted on
Sat Jan 06, 2024 10:58 am
neilk offline
Posts: 715
Joined: Jul 13, 2015
Location: Reading, UK

Re: Plugin help

So the moment of truth, lets bring it all together

Code: Select all
#!/usr/bin/env python3
"""Simple test of new API Changes."""
import asyncio
import json
import pprint
from datetime import date, timedelta
from urllib.request import Request, urlopen
from mytoyota.client import MyT
from mytoyota.models.summary import SummaryType

pp = pprint.PrettyPrinter(indent=4)

# Again from the example add your details below, including the correct variable ID for mileage, fuel, battery and latitude
# For the reflector name, just include the unique portion before the first . rather than the full URL
REFLECTORNAME = "reflector"
APIKEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
MILEAGEVARIABLE = 520855978
FUELVARIABLE = 1598525448
BATTERYVARIABLE = 1947159701
LATITUDEVARIABLE = 93775207
# you can add more variables if you want to expose other data to indigo
#BATTERYRANGEVARIABLE = 4848583483

# now define a function (so we don't need to repeat the code to set each variable, we will call it later but it is the code from the http api python example

def set_indigo_variable(VARIABLEID, VALUE):
    message = json.dumps({
        "id": "toyota",
        "message": "indigo.variable.updateValue",
        "objectId": VARIABLEID,
        "parameters": {
            # this is modified to use VALUE that is passed to the function to updated the indigo variable rather than "Some string value" in the example code
            "value": VALUE
        }
    }).encode("utf8")
    req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/command", data=message)
    req.add_header('Authorization', f"Bearer {APIKEY}")
    with urlopen(req) as request:
        reply = json.load(request)
        print(reply)



# Set your username and password in a file on top level called "credentials.json" in the format:
#   {
#       "username": "<username>",
#       "password": "<password>"
#   }


def load_credentials():
    """Load credentials from 'credentials.json'."""
    try:
        with open("credentials.json", encoding="utf-8") as f:
            return json.load(f)
    except (FileNotFoundError, json.decoder.JSONDecodeError):
        return None


credentials = load_credentials()
if not credentials:
    raise ValueError(
        "Did you forget to set your username and password? Or supply the credentials file"
    )

USERNAME = credentials["username"]
PASSWORD = credentials["password"]

client = MyT(username=USERNAME, password=PASSWORD)


async def get_information():
    """Test login and output from endpoints."""
    print("Logging in...")
    await client.login()

    print("Retrieving cars...")
    cars = await client.get_vehicles(metric=False)

    for car in cars:
        await car.update()

        # Dashboard Information
        pp.pprint(f"Dashboard: {car.dashboard}")

        # select the data we want

        mileage = car.dashboard.odometer
        battery = car.dashboard.fuel_level
        fuel = car.dashboard.battery_level
        #if you want more (say "battery_range") then add a line like below (or uncomment that one)
        #battery_range = car.dashboard.battery_range



        #not sure if you needed latitude, I just updated with "location" which I have guessed is a string
        #comment out if you don't need it
        latitude = car.location
       
        # now update the variables
        set_indigo_variable(MILEAGEVARIABLE, str(mileage))
        set_indigo_variable(FUELVARIABLE, str(fuel))
        set_indigo_variable(BATTERYVARIABLE, str(battery))
        set_indigo_variable(LATITUDEVARIABLE, latitude)
        #And if you want to add battery range then uncomment then line below
        #set_indigo_variable(BATTERYRANGEVARIABLE, str(battery_range))




        # Location Information
        #pp.pprint(f"Location: {car.location}")
        # Lock Status
        #pp.pprint(f"Lock Status: {car.lock_status}")
        # Notifications
        #pp.pprint(f"Notifications: {[[x] for x in car.notifications]}")
        # Summary
        # pp.pprint(
        #    f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=7), date.today(), summary_type=SummaryType.DAILY)]}"  # noqa: E501 # pylint: disable=C0301
        # )
        # pp.pprint(
        #    f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=7 * 4), date.today(), summary_type=SummaryType.WEEKLY)]}"  # noqa: E501 # pylint: disable=C0301
        # )
        #pp.pprint(
        #    f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=6 * 30), date.today(), summary_type=SummaryType.MONTHLY)]}"  # noqa: E501
        #)
        # pp.pprint(
        #    f"Summary: {[[x] for x in await car.get_summary(date.today() - timedelta(days=365), date.today(), summary_type=SummaryType.YEARLY)]}"  # noqa: E501 # pylint: disable=C0301
        # )

        # Trips
        #pp.pprint(
        #    f"Trips: f{await car.get_trips(date.today() - timedelta(days=7), date.today(), full_route=True)}"  # noqa: E501
        #)

        # Dump all the information collected so far:
        # pp.pprint(car._dump_all())


loop = asyncio.new_event_loop()
loop.run_until_complete(get_information())
loop.close()


I have added comments and examples to show you how to add the other data points from your example (you would also need to create an indigo variable) bit you could do the same for the other data points.

Run this and see if it updates the indigo variables, we can the go ahead and run it on a schedule

Posted on
Sat Jan 06, 2024 12:44 pm
mwoodage offline
User avatar
Posts: 174
Joined: Dec 19, 2014
Location: Devon UK

Re: Plugin help

Wow! It's working :D

I've had a bit of a play around with the variables and what gets updated, but so far this is what i'm getting - thank you so much :D

Code: Select all
martin@Martins-Mac-mini-2 Totota % python3 indigo_variables.py
Logging in...
Retrieving cars...
('Dashboard: odometer=4597.0 fuel_level=51 battery_level=33 fuel_range=207.0 '
 'battery_range=0.0 battery_range_with_ac=0.0 range=206.917 '
 'charging_status=plugged remaining_charge_time=None warning_lights=[]')
{'success': 'message sent to the Indigo Server, check the Event Log for details', 'id': 'toyota'}
{'success': 'message sent to the Indigo Server, check the Event Log for details', 'id': 'toyota'}
{'success': 'message sent to the Indigo Server, check the Event Log for details', 'id': 'toyota'}
{'success': 'message sent to the Indigo Server, check the Event Log for details', 'id': 'toyota'}
martin@Martins-Mac-mini-2 Totota %


Screenshot 2024-01-06 at 18.35.44.png
Screenshot 2024-01-06 at 18.35.44.png (71.67 KiB) Viewed 805 times


The battery range is 0 as we've been out today and used up all the battery, so on charge tonight!

I'll look over what else I'd like to display on a control page, I see lock status is an option so I could use that, but recon i'd be able to implement things now.

Thank you so much for spending the time helping me with this, i've learnt so much along the way. At some point i think coding lessons for me would be a good idea - who do you use for your on-line course?

Thanks
Martin

Posted on
Sat Jan 06, 2024 12:47 pm
DaveL17 offline
User avatar
Posts: 6759
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Plugin help

mwoodage wrote:
who do you use for your on-line course?

I would recommend a dude called "Net Ninja" on YouTube. His lessons are in nice, bite-sized chunks and he's a very good instructor.

https://youtube.com/playlist?list=PL4cUxeGkcC9idu6GZ8EU_5B6WpKTdYZbK&feature=shared

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Sat Jan 06, 2024 1:02 pm
mwoodage offline
User avatar
Posts: 174
Joined: Dec 19, 2014
Location: Devon UK

Re: Plugin help

Thanks Dave, i'll take a look :D

Posted on
Sun Jan 07, 2024 12:59 pm
mwoodage offline
User avatar
Posts: 174
Joined: Dec 19, 2014
Location: Devon UK

Re: Plugin help

Just when i thought i'd cracked it........

Everything works perfectly when running from terminal - however when i set a schedule to execute the same script, i get this in the indigo error log,

Code: Select all
7 Jan 2024 at 18:57:12
   Schedule                        Toyota Status Update
   Script Error                    schedule "Toyota Status Update" script error in file indigo_variables.py:
   Script Error                    No module named 'mytoyota.models.summary'
   Script Error                    Exception Traceback (most recent call shown last):

     indigo_variables.py, line 9, at top level
ModuleNotFoundError: No module named 'mytoyota.models.summary'


It’s the same script in the same folder - I’m assuming I’m doing something wrong, but what!

M

Posted on
Sun Jan 07, 2024 1:33 pm
neilk offline
Posts: 715
Joined: Jul 13, 2015
Location: Reading, UK

Re: Plugin help

The issue is as per Jay's comment, this will not work when executed by the Indigo python instance (to do with the use of asyncio) so you need to change the schedule action from "run script" to "run shell script"

This should sort it, presuming you have made it executable ( chmod +x scriptname.py)


If that has worked you should also be able to run the script (when you are in the directory where the script is stored) by typing "./scriptname.py"

This will run it in the same way as when you do from the terminal.

We could do some housekeeping to tidy the script up as you will never see the output, and for example to update a variable with a time stamp of the most recent update (so you can see if the uodates are stale and broken).

Posted on
Sun Jan 07, 2024 1:35 pm
FlyingDiver offline
User avatar
Posts: 7222
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Plugin help

You need to put your script, and all the modules that it needs, in:

Code: Select all
/Library/Application Support/Perceptive Automation/Python3-includes


Well, to be more accurate, the modules need to be there. The script can be anywhere, but if you put it in the above folder it will be copied over to the new location when Indigo is updated.

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Sun Jan 07, 2024 1:38 pm
FlyingDiver offline
User avatar
Posts: 7222
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Plugin help

neilk wrote:
The issue is as per Jay's comment, this will not work when executed by the Indigo python instance (to do with the use of asyncio) so you need to change the schedule action from "run script" to "run shell script"


I'm not sure Jay is correct on this. There's nothing magic about asyncio if the script is complete and waits until the async function is done.

The error he's getting is an import error, caused by the module he's importing not being in the Python path.

Try my fix first.

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Sun Jan 07, 2024 2:16 pm
mwoodage offline
User avatar
Posts: 174
Joined: Dec 19, 2014
Location: Devon UK

Re: Plugin help

Hello, thanks both for your replies, results are below,

Joe

I've put all the files into the Python3 includes file and get the following result,

Screenshot 2024-01-07 at 19.59.18.png
Screenshot 2024-01-07 at 19.59.18.png (102.24 KiB) Viewed 646 times


Code: Select all
7 Jan 2024 at 19:46:20
   Script Error                    script error in file indigo_variables.py:
   Script Error                    Did you forget to set your username and password? Or supply the credentials file
   Script Error                    Exception Traceback (most recent call shown last):

     indigo_variables.py, line 62, at top level
ValueError: Did you forget to set your username and password? Or supply the credentials file


The credentials file is in the same folder credentials.json. I've tried adding the username and password to the script, but that didn't work ether.


Neil,

I've made the script excitable and tried that as Run Shell Script, i get this, nothing else and nothing updates

Code: Select all
7 Jan 2024 at 20:03:35
   Schedule                        Toyota Status Update


Or if i run it as Execute script i get the following error, which is the same as the one above,

Code: Select all
   Script Error                    script error in file indigo_variables.py:
   Script Error                    Did you forget to set your username and password? Or supply the credentials file
   Script Error                    Exception Traceback (most recent call shown last):

     indigo_variables.py, line 62, at top level
ValueError: Did you forget to set your username and password? Or supply the credentials file


Sorry it's causing so many problems!
M

Posted on
Sun Jan 07, 2024 2:24 pm
FlyingDiver offline
User avatar
Posts: 7222
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Plugin help

Check the permissions on the credentials.json file. It's got to be readable by the plugin process.

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Sun Jan 07, 2024 2:56 pm
neilk offline
Posts: 715
Joined: Jul 13, 2015
Location: Reading, UK

Re: Plugin help

I am sure Joe is right, the potential issue with asyncio was an assumption on my part based on the earlier comments.

If you are not sure on how to check/correct the permissions then just shout but https://www.macinstruct.com/tutorials/how-to-set-file-permissions-on-a-mac/ should help

If it is still no joy, then we can tweak the script that will allow you to embed the credentials in the file ( we will need to remove the code that pulls them from the credentials file rather than simply adding them).

Posted on
Sun Jan 07, 2024 3:15 pm
mwoodage offline
User avatar
Posts: 174
Joined: Dec 19, 2014
Location: Devon UK

Re: Plugin help

Umm, i've checked the permissions and it's all set to read/write for that file. I've even tried producing a new credentials file but that's not worked ether.

A while ago i saw in one of the Mytoyota scripts that you could put your username and password in the main body of the script, so i'll dig that out and give it a try - if i get stuck i'll come back to you both. I'll also let you know if i fix it :D

Thanks
M

Posted on
Sun Jan 07, 2024 3:21 pm
ryanbuckner offline
Posts: 1080
Joined: Oct 08, 2011
Location: Northern Virginia

Re: Plugin help

you can hard code your username and password technically, it's just not as secure as using a creds file

Posted on
Sun Jan 07, 2024 4:30 pm
neilk offline
Posts: 715
Joined: Jul 13, 2015
Location: Reading, UK

Re: Plugin help

The other thing you could try is putting the full path to the credentials file in this line

Code: Select all
         with open("credentials.json", encoding="utf-8") as f:


I have lost track as to which is the final script and which folder it is in !

Who is online

Users browsing this forum: No registered users and 7 guests