Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show only direct connections #19

Closed
nbarrientos opened this issue Mar 23, 2024 · 12 comments
Closed

Show only direct connections #19

nbarrientos opened this issue Mar 23, 2024 · 12 comments

Comments

@nbarrientos
Copy link

Hi,

Sorry for posting here stuff about the HA integration but I thought it'd be faster to reach you :)

Would it be feasible to patch the HA integration to configure a given connection to only show direct connections? This lib and the API seem to support it.

It does not seem complicated: maybe an extra user_input in config_flow which would enable the direct parameter in the OpendataTransport object. I don't have much experience touching the HA codebase but I can try.

What do you think?

@nbarrientos
Copy link
Author

Maybe I spoke too fast: OpendataCH/Transport#216

@nbarrientos
Copy link
Author

So yeah, according to the reply in the ticket above the direct parameter (and many more) are not supported anymore.

There's still the chance to keep the parameter in the library and do the filtering at this stage to kind of simulate the missing functionality in the API. Would you be willing to review a patch to do so?

@nbarrientos
Copy link
Author

Ping @miaucl

@miaucl
Copy link
Contributor

miaucl commented Apr 1, 2024

Hey guys, as you might know, it takes some time to integrate into HA and as it was a old integration, the focus lies first on clean up before new features are considered. But yes, this is already on my radar 👍

@nbarrientos
Copy link
Author

Great, if I can help somehow here I am. I'm specially interested in being able to filter out non-direct connections, preferably at HA level. I've seen a patch of yours has been recently merged in HA to have separate entities per departure. If each departure_x had the transfers attribute it'd be easy to filter in templates, for instance.

@miaucl
Copy link
Contributor

miaucl commented Feb 9, 2025

@nbarrientos Still relevant, otherwise I would ask you to close this issue :)

@nbarrientos
Copy link
Author

Hi,

Yes, it is. Actually I have to patch locally home assistant every time I upgrade it due to this :D

@miaucl
Copy link
Contributor

miaucl commented Feb 10, 2025

Hey, I created following PR to remove those fields as they are not supported anymore by the opendata api.

--> http://transport.opendata.ch/docs.html#connections

See this PR: #28

Once this is merged, feel free to propose a solution in this lib to implement post-request handling.

@nbarrientos
Copy link
Author

Hi,

The API doesn't indeed allow anymore to query for direct connections, however the connection object ships a transfers field (undocumented in the API docs, but consumed by this lib), ex:

[~]@malt
λ curl "http://transport.opendata.ch/v1/connections?from=Lausanne&to=Genève" | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 21316  100 21316    0     0  63883      0 --:--:-- --:--:-- --:--:-- 64012
{
  "connections": [
    {
      "from": {
        "station": {
          "id": "8501120",
          "name": "Lausanne",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.516795,
            "y": 6.629087
          },
          "distance": null
        },
        "arrival": null,
        "arrivalTimestamp": null,
        "departure": "2025-02-11T10:46:00+0100",
        "departureTimestamp": 1739267160,
        "delay": 2,
        "platform": "4",
        "prognosis": {
          "platform": null,
          "arrival": null,
          "departure": "2025-02-11T10:48:00+0100",
          "capacity1st": null,
          "capacity2nd": null
        },
        "realtimeAvailability": null,
        "location": {
          "id": "8501120",
          "name": "Lausanne",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.516795,
            "y": 6.629087
          },
          "distance": null
        }
      },
      "to": {
        "station": {
          "id": "8501008",
          "name": "Genève",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.210228,
            "y": 6.142435
          },
          "distance": null
        },
        "arrival": "2025-02-11T11:25:00+0100",
        "arrivalTimestamp": 1739269500,
        "departure": null,
        "departureTimestamp": null,
        "delay": null,
        "platform": "3",
        "prognosis": {
          "platform": null,
          "arrival": null,
          "departure": null,
          "capacity1st": null,
          "capacity2nd": null
        },
        "realtimeAvailability": null,
        "location": {
          "id": "8501008",
          "name": "Genève",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.210228,
            "y": 6.142435
          },
          "distance": null
        }
      },
      "duration": "00d00:39:00",
      "transfers": 0, <----- this one
      "service": null,
      "products": [
        "IC 1"
      ],
      "capacity1st": null,
      "capacity2nd": null,
      "sections": [
[...]
}

so what I'm currently doing is to maintain a dirty patch for the Swiss public transport Home Assistant component to hardcode a filter for only direct connections, something like:

diff --git a/homeassistant/components/swiss_public_transport/__init__.py b/homeassistant/components/swiss_public_transport/__init__.py
index 628f6e95c2a..2eceec68020 100644
--- a/homeassistant/components/swiss_public_transport/__init__.py
+++ b/homeassistant/components/swiss_public_transport/__init__.py
@@ -70,6 +70,7 @@ async def async_setup_entry(
         via=config.get(CONF_VIA),
         time=config.get(CONF_TIME_FIXED),
         isArrivalTime=config.get(CONF_TIME_STATION, DEFAULT_TIME_STATION) == "arrival",
+        limit=10,
     )
     if time_offset:
         offset_opendata(opendata, time_offset)
diff --git a/homeassistant/components/swiss_public_transport/config_flow.py b/homeassistant/components/swiss_public_transport/config_flow.py
index 58d674f0c26..fc633ec6a24 100644
--- a/homeassistant/components/swiss_public_transport/config_flow.py
+++ b/homeassistant/components/swiss_public_transport/config_flow.py
@@ -182,6 +182,7 @@ class SwissPublicTransportConfigFlow(ConfigFlow, domain=DOMAIN):
                 session,
                 via=input.get(CONF_VIA),
                 time=input.get(CONF_TIME_FIXED),
+                limit=10,
             )
             if time_offset:
                 offset_opendata(opendata, time_offset)
diff --git a/homeassistant/components/swiss_public_transport/coordinator.py b/homeassistant/components/swiss_public_transport/coordinator.py
index c4cf2390dd0..7981d7d4427 100644
--- a/homeassistant/components/swiss_public_transport/coordinator.py
+++ b/homeassistant/components/swiss_public_transport/coordinator.py
@@ -101,6 +101,10 @@ class SwissPublicTransportDataUpdateCoordinator(
                 "Unable to connect and retrieve data from transport.opendata.ch"
             )
             raise UpdateFailed from e
+
+        only_direct = list(filter(lambda v: v["transfers"] == 0, self._opendata.connections.values()))
+        self._opendata.connections = dict(zip(range(len(only_direct)), only_direct))
+
         connections = self._opendata.connections
         return [
             DataConnection(
-- 
2.47.0
EOF

So, instead of hardcoding it (if this is a field we can rely on) we could just leave this library as is and then do the filtering in HA by adding for instance a checkbox to the "add device" dialog:

Image

to basically make the patch above conditional to the setting.

Does that make sense?

@miaucl
Copy link
Contributor

miaucl commented Feb 11, 2025

Hi,

The API doesn't indeed allow anymore to query for direct connections, however the connection object ships a transfers field (undocumented in the API docs, but consumed by this lib), ex:

[~]@malt
λ curl "http://transport.opendata.ch/v1/connections?from=Lausanne&to=Genève" | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 21316  100 21316    0     0  63883      0 --:--:-- --:--:-- --:--:-- 64012
{
  "connections": [
    {
      "from": {
        "station": {
          "id": "8501120",
          "name": "Lausanne",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.516795,
            "y": 6.629087
          },
          "distance": null
        },
        "arrival": null,
        "arrivalTimestamp": null,
        "departure": "2025-02-11T10:46:00+0100",
        "departureTimestamp": 1739267160,
        "delay": 2,
        "platform": "4",
        "prognosis": {
          "platform": null,
          "arrival": null,
          "departure": "2025-02-11T10:48:00+0100",
          "capacity1st": null,
          "capacity2nd": null
        },
        "realtimeAvailability": null,
        "location": {
          "id": "8501120",
          "name": "Lausanne",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.516795,
            "y": 6.629087
          },
          "distance": null
        }
      },
      "to": {
        "station": {
          "id": "8501008",
          "name": "Genève",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.210228,
            "y": 6.142435
          },
          "distance": null
        },
        "arrival": "2025-02-11T11:25:00+0100",
        "arrivalTimestamp": 1739269500,
        "departure": null,
        "departureTimestamp": null,
        "delay": null,
        "platform": "3",
        "prognosis": {
          "platform": null,
          "arrival": null,
          "departure": null,
          "capacity1st": null,
          "capacity2nd": null
        },
        "realtimeAvailability": null,
        "location": {
          "id": "8501008",
          "name": "Genève",
          "score": null,
          "coordinate": {
            "type": "WGS84",
            "x": 46.210228,
            "y": 6.142435
          },
          "distance": null
        }
      },
      "duration": "00d00:39:00",
      "transfers": 0, <----- this one
      "service": null,
      "products": [
        "IC 1"
      ],
      "capacity1st": null,
      "capacity2nd": null,
      "sections": [
[...]
}

so what I'm currently doing is to maintain a dirty patch for the Swiss public transport Home Assistant component to hardcode a filter for only direct connections, something like:

diff --git a/homeassistant/components/swiss_public_transport/__init__.py b/homeassistant/components/swiss_public_transport/__init__.py
index 628f6e95c2a..2eceec68020 100644
--- a/homeassistant/components/swiss_public_transport/__init__.py
+++ b/homeassistant/components/swiss_public_transport/__init__.py
@@ -70,6 +70,7 @@ async def async_setup_entry(
         via=config.get(CONF_VIA),
         time=config.get(CONF_TIME_FIXED),
         isArrivalTime=config.get(CONF_TIME_STATION, DEFAULT_TIME_STATION) == "arrival",
+        limit=10,
     )
     if time_offset:
         offset_opendata(opendata, time_offset)
diff --git a/homeassistant/components/swiss_public_transport/config_flow.py b/homeassistant/components/swiss_public_transport/config_flow.py
index 58d674f0c26..fc633ec6a24 100644
--- a/homeassistant/components/swiss_public_transport/config_flow.py
+++ b/homeassistant/components/swiss_public_transport/config_flow.py
@@ -182,6 +182,7 @@ class SwissPublicTransportConfigFlow(ConfigFlow, domain=DOMAIN):
                 session,
                 via=input.get(CONF_VIA),
                 time=input.get(CONF_TIME_FIXED),
+                limit=10,
             )
             if time_offset:
                 offset_opendata(opendata, time_offset)
diff --git a/homeassistant/components/swiss_public_transport/coordinator.py b/homeassistant/components/swiss_public_transport/coordinator.py
index c4cf2390dd0..7981d7d4427 100644
--- a/homeassistant/components/swiss_public_transport/coordinator.py
+++ b/homeassistant/components/swiss_public_transport/coordinator.py
@@ -101,6 +101,10 @@ class SwissPublicTransportDataUpdateCoordinator(
                 "Unable to connect and retrieve data from transport.opendata.ch"
             )
             raise UpdateFailed from e
+
+        only_direct = list(filter(lambda v: v["transfers"] == 0, self._opendata.connections.values()))
+        self._opendata.connections = dict(zip(range(len(only_direct)), only_direct))
+
         connections = self._opendata.connections
         return [
             DataConnection(
-- 
2.47.0
EOF

So, instead of hardcoding it (if this is a field we can rely on) we could just leave this library as is and then do the filtering in HA by adding for instance a checkbox to the "add device" dialog:

Image

to basically make the patch above conditional to the setting.

Does that make sense?

Yes I got that, unfortunately home assistant wont allow that being inplemented I think. But you can ask in the dev Channel on discord what you should do in that case. They are quite responsive there!

I just see a problem, that with post filtering you never know how many connections you will get if any at all. This is not clean...

There, why not use fetch_connections service call for stuff like that?

@miaucl
Copy link
Contributor

miaucl commented Feb 11, 2025

Like so

image

@nbarrientos
Copy link
Author

There, why not use fetch_connections service call for stuff like that?

Thanks for the suggestion. I'll take a look at this as soon as I have time.

The ticket anyway can be closed, I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants