tdorssers / TeslaPy

A Python module to use the Tesla Motors Owner API
MIT License
374 stars 84 forks source link

Crash in vehicle_list() #69

Closed SylvainGa closed 2 years ago

SylvainGa commented 2 years ago

Got the following crash this morning. I've 'bolded' the line that I think in my source code generated the crash. I'm using a refresh token to connect. It runs without issue for several hours. Not sure if it's about the access token expiring. The next expiration is today at 11:02:00 PM local time. I'll see if it does it then.

The source is at https://github.com/SylvainGa/TeslaRainCheck


Apr 15 11:31:06 weewx python3[20670]: Traceback (most recent call last):
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
Apr 15 11:31:06 weewx python3[20670]:     chunked=chunked)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 384, in _make_request
Apr 15 11:31:06 weewx python3[20670]:     six.raise_from(e, None)
Apr 15 11:31:06 weewx python3[20670]:   File "<string>", line 3, in raise_from
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 380, in _make_request
Apr 15 11:31:06 weewx python3[20670]:     httplib_response = conn.getresponse()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3.7/http/client.py", line 1352, in getresponse
Apr 15 11:31:06 weewx python3[20670]:     response.begin()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3.7/http/client.py", line 310, in begin
Apr 15 11:31:06 weewx python3[20670]:     version, status, reason = self._read_status()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3.7/http/client.py", line 279, in _read_status
Apr 15 11:31:06 weewx python3[20670]:     raise RemoteDisconnected("Remote end closed connection without"
Apr 15 11:31:06 weewx python3[20670]: http.client.RemoteDisconnected: Remote end closed connection without response
Apr 15 11:31:06 weewx python3[20670]: During handling of the above exception, another exception occurred:
Apr 15 11:31:06 weewx python3[20670]: Traceback (most recent call last):
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
Apr 15 11:31:06 weewx python3[20670]:     timeout=timeout
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
Apr 15 11:31:06 weewx python3[20670]:     _stacktrace=sys.exc_info()[2])
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 367, in increment
Apr 15 11:31:06 weewx python3[20670]:     raise six.reraise(type(error), error, _stacktrace)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/six.py", line 692, in reraise
Apr 15 11:31:06 weewx python3[20670]:     raise value.with_traceback(tb)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
Apr 15 11:31:06 weewx python3[20670]:     chunked=chunked)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 384, in _make_request
Apr 15 11:31:06 weewx python3[20670]:     six.raise_from(e, None)
Apr 15 11:31:06 weewx python3[20670]:   File "<string>", line 3, in raise_from
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 380, in _make_request
Apr 15 11:31:06 weewx python3[20670]:     httplib_response = conn.getresponse()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3.7/http/client.py", line 1352, in getresponse
Apr 15 11:31:06 weewx python3[20670]:     response.begin()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3.7/http/client.py", line 310, in begin
Apr 15 11:31:06 weewx python3[20670]:     version, status, reason = self._read_status()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3.7/http/client.py", line 279, in _read_status
Apr 15 11:31:06 weewx python3[20670]:     raise RemoteDisconnected("Remote end closed connection without"
Apr 15 11:31:06 weewx python3[20670]: urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Apr 15 11:31:06 weewx python3[20670]: During handling of the above exception, another exception occurred:
Apr 15 11:31:06 weewx python3[20670]: Traceback (most recent call last):
Apr 15 11:31:06 weewx python3[20670]:   File "/home/pi/tesla/check_tesla_windows_mqtt.py", line 216, in <module>
Apr 15 11:31:06 weewx python3[20670]:     client.loop_forever()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 1756, in loop_forever
Apr 15 11:31:06 weewx python3[20670]:     rc = self._loop(timeout)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 1164, in _loop
Apr 15 11:31:06 weewx python3[20670]:     rc = self.loop_read()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 1556, in loop_read
Apr 15 11:31:06 weewx python3[20670]:     rc = self._packet_read()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 2439, in _packet_read
Apr 15 11:31:06 weewx python3[20670]:     rc = self._packet_handle()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 3033, in _packet_handle
Apr 15 11:31:06 weewx python3[20670]:     return self._handle_publish()
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 3327, in _handle_publish
Apr 15 11:31:06 weewx python3[20670]:     self._handle_on_message(message)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
Apr 15 11:31:06 weewx python3[20670]:     on_message(self, self._userdata, message)
Apr 15 11:31:06 weewx python3[20670]:   File "/home/pi/tesla/check_tesla_windows_mqtt.py", line 87, in on_message
**Apr 15 11:31:06 weewx python3[20670]:     vehicles = tesla.vehicle_list()**
Apr 15 11:31:06 weewx python3[20670]:   File "./TeslaPy/teslapy/__init__.py", line 351, in vehicle_list
Apr 15 11:31:06 weewx python3[20670]:     return [Vehicle(v, self) for v in self.api('VEHICLE_LIST')['response']]
Apr 15 11:31:06 weewx python3[20670]:   File "./TeslaPy/teslapy/__init__.py", line 347, in api
Apr 15 11:31:06 weewx python3[20670]:     **{arg_name: kwargs})
Apr 15 11:31:06 weewx python3[20670]:   File "./TeslaPy/teslapy/__init__.py", line 141, in request
Apr 15 11:31:06 weewx python3[20670]:     response = super(Tesla, self).request(method, url, **kwargs)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/requests_oauthlib/oauth2_session.py", line 360, in request
Apr 15 11:31:06 weewx python3[20670]:     headers=headers, data=data, **kwargs)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
Apr 15 11:31:06 weewx python3[20670]:     resp = self.send(prep, **send_kwargs)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
Apr 15 11:31:06 weewx python3[20670]:     r = adapter.send(request, **kwargs)
Apr 15 11:31:06 weewx python3[20670]:   File "/usr/lib/python3/dist-packages/requests/adapters.py", line 498, in send
Apr 15 11:31:06 weewx python3[20670]:     raise ConnectionError(err, request=request)
Apr 15 11:31:06 weewx python3[20670]: requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Apr 15 11:31:07 weewx systemd[1]: check_tesla_windows_mqtt.service: Main process exited, code=exited, status=1/FAILURE
Apr 15 11:31:07 weewx systemd[1]: check_tesla_windows_mqtt.service: Failed with result 'exit-code'.
tdorssers commented 2 years ago

You can try to enable retries, so requests will retry after a connection aborted exception:

with teslapy.Tesla(username, retry=3, timeout=20) as tesla:

You can even have TeslaPy retry HTTP exceptions:

retry = teslapy.Retry(total=3, status_forcelist=(500, 502, 503, 504)) with teslapy.Tesla(username, retry=retry, timeout=20) as tesla:

SylvainGa commented 2 years ago

Thanks, I'll give it a try.

SylvainGa commented 2 years ago

No crash today with the addition of the retry and timeout parameters. I'll report back tomorrow and close the issue if all is well, thanks.

tdorssers commented 2 years ago

Great. The reason that retries aren't enabled by default, is that if you hammer the API too much, your account can be blocked temporarily. But if you retry a couple of times and back off a while and retry again, then it shouldn't be an issue.

SylvainGa commented 2 years ago

Hi, it crashed again reading the following line: vehicleData = vehicles[vehicle].get_vehicle_data() With a 408 exception. The line just before that was if vehicles[vehicle].available() == True: # Only read if the car isn't asleep From what I got in your doc for 'available':

checks if the vehicle is online based on cached data or refreshed status when aged out

It looks like the car went offline before the cache aged out.

I'm just starting with Python and not sure I would go about forcing a cache refresh before the 'available()' call or adding a HTTPError 408 exception around that 'get_vehicle_data()' so it acts as if the car is offline when it's thrown.

For now, i'm doing my own 'available' check as such

available = False
vehicles = tesla.vehicle_list()
if vehicles[vehicle]['state'] != 'asleep':
    available = True

Wondering if there is a better way.

Thanks,

tdorssers commented 2 years ago

I would catch the 408 exception, because it takes about 30 seconds for the car to actually go to sleep.

SylvainGa commented 2 years ago

Thanks, I've set the retry and connection parameters as such

retry = teslapy.Retry(total=5, status_forcelist=(408, 500, 502, 503, 504, 540)) tesla = teslapy.Tesla(Config.get('Tesla', 'username'), retry=retry, timeout=10)

I'll see how it goes in the following days. Thanks for maintaining this library btw :-)

SylvainGa commented 2 years ago

Has been stable since my last post 5 days ago. I'll go ahead and close this issue. Thanks for your help :-)

I do wish Tesla would implement internally what I'm doing here, which is when rain is detected (it does already), close the windows if the car is parked. Could work similar to cabin overheat protection. It would work everywhere, not just close to my weather station.

SylvainGa commented 2 years ago

Working, thanks for your help.