msp1974 / homeassistant-jlrincontrol

An integration for JLR InControl to Home Assistant
MIT License
64 stars 11 forks source link

HTTP Error 503: Backend fetch failed #1

Closed x6ryK3Bomur6hm closed 4 years ago

x6ryK3Bomur6hm commented 4 years ago

I tried this integration, having previously used the one from rb28z2 which worked well. But I can't get past the login, getting a 503 error.

Installation: The jlrincontrol folder is placed in the custom_components directory

Configuration.yaml file: jlrincontrol: username: xxxxxx@xxxx.com password: xxxxxx

Note: I did not include name: in the config, which was required in rb28z2's version but not in this version. Edit: spaces seem to be left out in this comment but spacing is correct in my config file.

Error in frontend The following integrations and platforms could not be set up: jlrincontrol Please check your config.

Log: 2020-04-16 09:05:34 ERROR (MainThread) [homeassistant.setup] Error during setup of component jlrincontrol Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/setup.py", line 171, in _async_setup_component hass, processed_config File "/config/custom_components/jlrincontrol/init.py", line 104, in async_setup await data.async_update() File "/config/custom_components/jlrincontrol/init.py", line 169, in async_update self.wakeup = self.vehicle.get_wakeup_time() File "/usr/local/lib/python3.7/site-packages/jlrpy.py", line 241, in get_wakeup_time return self.get("wakeuptime", headers) File "/usr/local/lib/python3.7/site-packages/jlrpy.py", line 592, in get return self.connection.get(command, '%s/vehicles/%s' % (IF9_BASE_URL, self.vin), headers) File "/usr/local/lib/python3.7/site-packages/jlrpy.py", line 71, in get return self.post(command, url, headers, None) File "/usr/local/lib/python3.7/site-packages/jlrpy.py", line 80, in post return self.open("%s/%s" % (url, command), headers=headers, data=data) File "/usr/local/lib/python3.7/site-packages/jlrpy.py", line 102, in open resp = opener.open(req) File "/usr/local/lib/python3.7/urllib/request.py", line 531, in open response = meth(req, response) File "/usr/local/lib/python3.7/urllib/request.py", line 641, in http_response 'http', request, response, code, msg, hdrs) File "/usr/local/lib/python3.7/urllib/request.py", line 569, in error return self._call_chain(args) File "/usr/local/lib/python3.7/urllib/request.py", line 503, in _call_chain result = func(args) File "/usr/local/lib/python3.7/urllib/request.py", line 649, in http_error_default raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 503: Backend fetch failed

I tried this integration earlier this week as well, when the version "jlrpy==1.3.2" was not yet specified in the manifest.json file. Then I got a similar error log, but ending in "HTTP Error 503: Service Unavailable". This was probably because I had been using rb28z2's version, which used version 1.2.0 of jlrpy.

Edit 2: I noticed in the sample images that this is used for a Jaguar XF. I have a Landrover Discovery Sport. Not sure if this may have influenced the error but wanted to add this info.

msp1974 commented 4 years ago

It looks like the get wake up time option is not available in a Disco. I think this is going to be one of the main challenges that not all options are available on all JLR models. I will update to better handle this today and let you know when committed.

MZorzy commented 4 years ago

same on RRS.

this is all vehicleStatus :


BATTERY_STATUS
BATTERY_VOLTAGE
BRAKE_FLUID_WARN
CLIMATE_STATUS_OPERATING_STATUS
CLIMATE_STATUS_REMAINING_RUNTIME
CLIMATE_STATUS_TIMER1_DAY
CLIMATE_STATUS_TIMER1_HOUR
CLIMATE_STATUS_TIMER1_MINUTE
CLIMATE_STATUS_TIMER1_MONTH
CLIMATE_STATUS_TIMER2_DAY
CLIMATE_STATUS_TIMER2_HOUR
CLIMATE_STATUS_TIMER2_MINUTE
CLIMATE_STATUS_TIMER2_MONTH
CLIMATE_STATUS_VENTING_TIME
DISTANCE_TO_EMPTY_FUEL
DOOR_BOOT_LOCK_STATUS
DOOR_BOOT_POSITION
DOOR_ENGINE_HOOD_LOCK_STATUS
DOOR_ENGINE_HOOD_POSITION
DOOR_FRONT_LEFT_LOCK_STATUS
DOOR_FRONT_LEFT_POSITION
DOOR_FRONT_RIGHT_LOCK_STATUS
DOOR_FRONT_RIGHT_POSITION
DOOR_REAR_LEFT_LOCK_STATUS
DOOR_REAR_LEFT_POSITION
DOOR_REAR_RIGHT_LOCK_STATUS
DOOR_REAR_RIGHT_POSITION
ENG_COOLANT_LEVEL_WARN
ENGINE_BLOCK
ENGINE_COOLANT_TEMP
EV_CHARGE_TYPE
EV_IS_CHARGING
EV_IS_PLUGGED_IN
EV_IS_PRECONDITIONING
EXT_KILOMETERS_TO_SERVICE
EXT_OIL_LEVEL_WARN
FUEL_LEVEL_PERC
IS_HEAD_LIGHTS_ON
IS_PANIC_ALARM_TRIGGERED
LATEST_COMPLETE_CONFIG_UPDATE
ODOMETER
ODOMETER_METER
ODOMETER_MILES
SERVICE_MODE_START
SERVICE_MODE_STOP
SRS_STATUS
THEFT_ALARM_STATUS
TRANSPORT_MODE_START
TRANSPORT_MODE_STOP
TU_ACTIVATION_STATUS
TU_STATUS_BUTTONS
TU_STATUS_CAN
TU_STATUS_CONFIG_VERSION
TU_STATUS_CRASH_INPUT
TU_STATUS_DAYS_SINCE_GNSS_FIX
TU_STATUS_EXT_HANDSFREE
TU_STATUS_EXT_POWER
TU_STATUS_GNSS
TU_STATUS_GNSS_ANTENNA
TU_STATUS_GSM_EXT_ANTENNA
TU_STATUS_GSM_MODEM
TU_STATUS_HANDSET
TU_STATUS_INT_POWER
TU_STATUS_INT_RTC
TU_STATUS_MIC
TU_STATUS_MOBILE_PHONE_CONNECTED
TU_STATUS_POWER
TU_STATUS_PRIMARY_CHARGE_PERCENT
TU_STATUS_PRIMARY_VOLT
TU_STATUS_SECONDARY_VOLT
TU_STATUS_SLEEP_CYCLES_START_TIME
TU_STATUS_SPEAKER
TYRE_PRESSURE_FRONT_LEFT
TYRE_PRESSURE_FRONT_RIGHT
TYRE_PRESSURE_REAR_LEFT
TYRE_PRESSURE_REAR_RIGHT
TYRE_STATUS_FRONT_LEFT
TYRE_STATUS_FRONT_RIGHT
TYRE_STATUS_REAR_LEFT
TYRE_STATUS_REAR_RIGHT
VEHICLE_STATE_TYPE
WASHER_FLUID_WARN
WINDOW_FRONT_LEFT_STATUS
WINDOW_FRONT_RIGHT_STATUS
WINDOW_REAR_LEFT_STATUS
WINDOW_REAR_RIGHT_STATUS
 
DOOR_IS_ALL_DOORS_LOCKED
ODOMETER_MILES_RESOLUTION
IS_SUNROOF_OPEN
PRIVACY_SWITCH
BRAZIL_EVENT_MODE
IS_CRASH_SITUATION
DOOR_IS_BOOT_LOCKED
IS_CAB_OPEN
TU_STATUS_USES_EXTERNAL_GNSS
ODOMETER_METER_RESOLUTION
CLIMATE_STATUS_TIMER_ACTIVATION_STATUS
 ```

and vehicleAlerts

DIST_TO_SERVICE_KM TRANSPORT_MODE ODOMETER_EXCEEDED ENGINE_ON



but looklike is an issue on jlrpy.py
x6ryK3Bomur6hm commented 4 years ago

Can confirm this seems to be an issue with not all options being available on all models. I got this integration working by removing the lines with "wakeup" from init.py and sensor.py. I also needed to remove the parts with "title" from sensor.py, otherwise I would get errors "AttributeError: 'NoneType' object has no attribute 'title' "

With those changes made the integration works without errors in the log, showing correct sensors on doors, info, range, service_info, tyres, windows, fuel.

Unfortunately no position data is revealed (longitude and latitude), although I can see the location of my car when I login to the official JLR website. EDIT: position data is working, I needed to set "track: true" in my known_devices.yaml - I have tracking new devices set to false by default, so this error was on my side. Tracking is quite accurate as well! This should be usefull as theft-tracking :-)

msp1974 commented 4 years ago

@stefanv84 updated the master branch to handle this better. Let me know if this has fixed it.

x6ryK3Bomur6hm commented 4 years ago

Great, this fixes the wakeup error and leads to a functioning integration.

Still an error remaining with the service_info sensor, making it unavailable.

Log: 2020-04-16 15:25:13 ERROR (MainThread) [homeassistant.util.logging] Exception in async_update_state when dispatching 'jlrincontrol.updated': () Traceback (most recent call last): File "/config/custom_components/jlrincontrol/init.py", line 285, in async_update_state await self.async_update_ha_state(True) File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 284, in async_update_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 328, in _async_write_ha_state attr.update(self.device_state_attributes or {}) File "/config/custom_components/jlrincontrol/sensor.py", line 172, in device_state_attributes attrs[k.title()] = s.get(v).title() AttributeError: 'NoneType' object has no attribute 'title'

If I block the following part from sensor.py, the sensor works, although it then only shows the main state and not the attributes. @property def device_state_attributes(self): s = self._data.status attrs = {} for k, v in DATA_ATTRS_SERVICE_STATUS.items(): attrs[k.title()] = s.get(v).title()

    return attrs
x6ryK3Bomur6hm commented 4 years ago

There is also another strange error related I believe to localization preferences. Putting it here but let me know if you want a seperate issue for this.

The range sensor is sometimes shown as in KMs and sometimes in Miles. With this I mean it seems to change randomly with different restarts of HASS, it does not change during a running session. When the range sensor is shown in KMs, the info sensor (which contains for example the odometer) breaks.

Log: 2020-04-16 15:20:51 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up jlrincontrol platform for sensor Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 186, in _async_setup_platform await asyncio.gather(pending) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 295, in async_add_entities await asyncio.gather(tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 447, in _async_add_entity await entity.async_update_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 284, in async_update_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 328, in _async_write_ha_state attr.update(self.device_state_attributes or {}) File "/config/custom_components/jlrincontrol/sensor.py", line 60, in device_state_attributes attrs["Odometer"] = self._data.get_odometer() File "/config/custom_components/jlrincontrol/init.py", line 201, in get_odometer return int(int(self.status.get("ODOMETER_METERS")) / 1000) TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

For the range sensor, the value is also shown as "332mi" or "535km", so the unit of measurement is not correctly defined. Because of this you cant use it in graph cards for example.

The preference stored in my official JLR website is "km". The options given are "mijl" and "km".

msp1974 commented 4 years ago

the integration reads those preferences from your account (on HA start) and sets the odometer and range to be in the units selected. Maybe this is trying to be too clever and it can't always read it. It will default to miles if it cannot get from your prefs in the app. I also looks like it is not reading the status in some instances, hence the NoneType exception. Maybe the webservice is not very robust. Will work on adding some better handling of these situations. And possibly the ability to set the units in config.

This is great feedback - thanks.

msp1974 commented 4 years ago

After some testing, it seems that the incontrol api more often than not does not return the user preferences when requesting get_user_info. I did have a typo when using Kms which can fix - should be ODOMETER_METER not METERS.

As such, let's have the settings in config.yaml. Will update.

msp1974 commented 4 years ago

Changed my mind on this as it annoyed me that I couldn't get the prefs from the app. As such, have added a repeat call to the api for up to 10 times to see if it returns the user prefs. Seems to be a max of 6/7 times in testing but now always returning and correctly displaying odometer and range in preferred units. If you can test and let me know. Thx

x6ryK3Bomur6hm commented 4 years ago

Tested it on a bunch of restarts and worked perfectly every time (my preference is km).

Only thing remaining now is the service_info sensor. I think the line in sensor.py should be: for k, v in DATA_ATTRS_SERVICE_STATUS.items(): attrs[k.title()] = s.get(v) and not for k, v in DATA_ATTRS_SERVICE_STATUS.items(): attrs[k.title()] = s.get(v).title() With this change the sensor is working correctly and showing all the attributes. edit: clarified this only applies to the SERVICE_STATUS part of sensor.py, the other parts work OK for me.

msp1974 commented 4 years ago

So i'm guessing it does not have one of the statuses for you. I will change so that if the status parameter is missing it will not include it. BTW which one is showing blank/unknown?

x6ryK3Bomur6hm commented 4 years ago

Below is the overview of all the attributes in the service_info sensor that I have:

Brake Fluid: NORMAL Coolant Level: NORMAL Dpf: - Engine Blockage: NORMAL_UNBLOCKED Exhaust Fluid: - Oil Level: NORMAL Washer Fluid: NORMAL

Fact that status of Dpf and exhaust fluid are empty is strange, because I have a diesel with diesel exhaust fluid (adblue).

msp1974 commented 4 years ago

That is strange. The sensor is pulling the right parameter as you can see below. Presume your Disco doesn't send these, unless they are called something different. As we develop this, it may be helpful to have an entry in the log to show the attributes and status data so we can use to diagnose these types of issues. I'll add that to the list of todo's. Going to work on the services and switches next. Anyway, update on master branch to not show missing attributes for now.

image

x6ryK3Bomur6hm commented 4 years ago

Thanks for fixing my issues, and great work on this integration. One of my favorite ones already.

Ill come back to the exaust fluid issue when it runs low, I think that my Disco does send a warning then but not sure.

msp1974 commented 4 years ago

That's great and really welcome your input to make this integration work across multiple vehicles. Closing this issue but feel free to open more if and when you find things not working.