davidorlea / homeassistant-aseag_next_bus

Custom Home Assistant component to retrieve next bus information from the ASEAG
MIT License
0 stars 4 forks source link

Outdated Api #1

Closed Zenchyi1 closed 2 years ago

Zenchyi1 commented 2 years ago

The Sensor wont show departure anymore and it seems like they changed the API Format. AVV wrote a Blog about their new API and to get the API mapping as well as an api key, you need to write them an E-Mail. image

davidorlea commented 2 years ago

Hi there, sorry for my late response. The legacy API is still in production. What is not working for you?

Zenchyi1 commented 2 years ago

Hello! I didnt know that its still in production, my bad! It still throws the error "TypeError: 'NoneType' object is not subscriptable" and shows the sensor value as unknown. Heres the log:

2022-07-30 13:20:28 ERROR (SyncWorker_4) [homeassistant.components.aseag_next_bus.sensor] awaiting response
2022-07-30 13:20:28 ERROR (SyncWorker_4) [homeassistant.components.aseag_next_bus.sensor] <Response [200]>
2022-07-30 13:20:28 ERROR (SyncWorker_4) [homeassistant.components.aseag_next_bus.sensor] {'sharingAvailability': None, 'departures': None, 'routeInformation': None}
2022-07-30 13:20:28 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.aseag_next_bus_1001_h_1 fails
Traceback (most recent call last):
  File "/workspaces/core/homeassistant/helpers/entity.py", line 487, in async_update_ha_state
    await self.async_device_update()
  File "/workspaces/core/homeassistant/helpers/entity.py", line 691, in async_device_update
    raise exc
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/workspaces/core/homeassistant/components/aseag_next_bus/sensor.py", line 133, in update
    d["stopPrediction"] for d in result["departures"]["departures"]
TypeError: 'NoneType' object is not subscriptable

And heres the code, i added some logging for debugging, didnt work before either tho, so its not that

    @staticmethod
    def get_predictions(stop_id):
        """Get predictions matching a stop from the ASEAG API."""
        headers = {"User-Agent": "curl/7.64.1"}
        resource = f"https://mova.aseag.de/mbroker/rest/areainformation/{stop_id}"
        try:
            _LOGGER.error("awaiting response")
            response = requests.get(resource, headers=headers, verify=True, timeout=10)
            _LOGGER.error(response)
            response.raise_for_status()
            _LOGGER.error(response.json())
            return response.json()
        except requests.exceptions.RequestException as ex:
            _LOGGER.error("Error fetching data: %s failed with %s", resource, ex)
            return None
        except ValueError as ex:
            _LOGGER.error("Error parsing data: %s failed with %s", resource, ex)
            return None

and im using this config :

- platform: aseag_next_bus
     name: aseag_next_bus
     mode: list
     stop_id: 1001
     track: 'H.1'
davidorlea commented 2 years ago

Thanks for the detailed logs! Which Python version and which Home Assistant version are you using?

Zenchyi1 commented 2 years ago

Python 3.10.5 and Home assistant core-2022.7.3

Eco-Gaming commented 2 years ago

Hey, i have the same problem. I tried running the API part as a simple standalone python script, however for me that produces the same results. Maybe it only works with a lower requests version? I ran the script with python 3.10.0 and requests 2.26.0.

import requests

stop_id = "1001"
headers = {"User-Agent": "curl/7.64.1"}
resource = f"https://mova.aseag.de/mbroker/rest/areainformation/{stop_id}"
response = ""
try:
    response = requests.get(resource, headers=headers, verify=True, timeout=10)
    response.raise_for_status()
except requests.exceptions.RequestException as ex:
    print("Error fetching data: %s failed with %s", resource, ex)
except ValueError as ex:
    print("Error parsing data: %s failed with %s", resource, ex)

print(response)
print(response.json())
print(requests.__version__)

Output:

<Response [200]>
{'sharingAvailability': None, 'departures': None, 'routeInformation': None}
2.26.0
davidorlea commented 2 years ago

The logs show that the API is not providing any departure information for the stop with ID 1001 and the integration is not correctly Null-checking this.

Where did you get the ID from? The API is the same as the web portal https://mova.aseag.de is using. (See requests in the Browser Developer Console.)

If you, for example, use the stop ID 23824 (Aachen Bushof), you will get results.

Eco-Gaming commented 2 years ago

OH, I think the problem was that we were using the stop ids from the new API. This blogpost that the first screenshot is from links to the opendata portal which has a csv with stops and stop ids, so I just assumed those were the right ones. (1001 is the ID for Aachen Bushof there). It works just fine with the ID you provided, however I don't quite understand how I'm supposed to get the IDs for other stops from the mova website. Could you maybe explain that in a bit more detail? Thanks!

Edit: I found what you meant in the browser console. For me however it always goes to a longer URL, which then uses the 'new' stop IDs. I'm just going to use this together with the csv mentioned above now: resource = f"https://mova.aseag.de/mbroker/rest/areainformation/publicTransport/sourceSystem/{stop_id}"

Zenchyi1 commented 2 years ago

Yeah im going to do the same for now, maybe update the link and then put the cvs in the docs sometime in the future so its easier to set up? Anyway thanks for helping out!

davidorlea commented 2 years ago

The APIs of ASEAG / AVV are a total mess and I am not aware of any "new", "old" or deprecation status on it. As far as I know, which is what I observe in the browser when navigating the map on https://mova.aseag.de, there are two types of REST endpoints that are called:

  1. Area information (https://mova.aseag.de/mbroker/rest/areainformation?locationWindow={latitude_a},{longitude_a},{latitude_b},{longitude_b}&placeOrOtherMobilityTypes=BUS_STOP), which provides a list of bus stops in this area.
  2. Stop information (https://mova.aseag.de/mbroker/rest/areainformation/{stop_id}), which provides a list of bus departures at this stop.

This is what my custom integration to Home Assistant is using.

Also, I am not aware of any "new" or "old" ID scheme for bus stops.

Zenchyi1 commented 2 years ago

All im aware of is that there is the current one implemented which has no real documentation, and then theres the system @Eco-Gaming and i use which does have a csv documentation of all the Bus stops and their ids and seems more official due to that. ÖPNV is a hot mess, nothing new here sadly.. If u'd like i could make a PR implementing the more Documented API just for ease of use, but seing as this works the way it is, its probably better to just leave it alone.

davidorlea commented 2 years ago

Is there some API documentation about real-time departure information of bus stops in the system your mentioned CSV belongs to?

Zenchyi1 commented 2 years ago

AFAIK its exactly the same response, the only think that would need to be changed is the URL and Bus stop ids, everything else is exactly the same. Ive got the URLs exchanged and nothings breaking.

davidorlea commented 2 years ago

Changing the ID scheme for bus stops would be a fundamental breaking change on this integration. If there are no other reasons, I would refrain from doing so.