Skip to content

Commit f68ea61

Browse files
Pulpyyyyclaude
andcommitted
Stable identity and readable labels for vehicle position markers
get_rt_vehicle_positions built properties.id and properties.title from the raw route_id, the direction and the last 3 digits of the crc32 of the trip_id. Two problems: - geo_json_events registers each marker with unique_id <config_entry_id>_<properties.id>. The crc32 of the trip_id changes on every trip, so every vehicle came back as a brand-new entity on each run and the entity registry grew without bound. - the title becomes the entity name on the map card, and labels like "ORLEANS:Line:40(0)156_bus" are unreadable there. Use the feed's vehicle id as the stable part of the identity (line_direction_vehicle) so a vehicle keeps the same entity across trips and days, and build the title from the line, the configured destination and the vehicle id ("40 -> Gaston Galloux 7015"). Fall back on the original crc-based id/label when the feed has no vehicle id or the config entry has no usable destination (local-stop sensors). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent b7e7e3b commit f68ea61

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

custom_components/gtfs2/gtfs_rt_helper.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,28 @@ def get_rt_vehicle_positions(self):
344344
geojson_element["geometry"]["coordinates"] = []
345345
geojson_element["geometry"]["coordinates"].append(vehicle["position"]["longitude"])
346346
geojson_element["geometry"]["coordinates"].append(vehicle["position"]["latitude"])
347-
geojson_element["properties"]["id"] = str(self._route_id) + "(" + str(vehicle["trip"]["direction_id"]) + ")" + str(binascii.crc32((vehicle["trip"]["trip_id"]).encode('utf8')))[-3:]
348-
geojson_element["properties"]["title"] = str(self._route_id) + "(" + str(vehicle["trip"]["direction_id"]) + ")" + str(binascii.crc32((vehicle["trip"]["trip_id"]).encode('utf8')))[-3:] + "_" + self._icon.split(':')[1]
347+
# Stable, human-readable marker identity.
348+
# geo_json_events registers each marker with unique_id
349+
# <config_entry_id>_<properties.id>; the crc32 of the trip_id changes
350+
# every trip, so each vehicle came back as a brand-new entity on every
351+
# run and the entity registry grew without bound. The vehicle id is
352+
# stable across trips and days, so the entity (and its name) is reused.
353+
# The map card uses the title as entity name; fall back on the original
354+
# crc-based label when the config entry carries no usable destination
355+
# (e.g. local-stop sensors) or the feed publishes no vehicle id.
356+
_line = str(self._route_id).split(":")[-1]
357+
_crc = str(binascii.crc32((vehicle["trip"]["trip_id"]).encode('utf8')))[-3:]
358+
_veh = str(vehicle.get("vehicle", {}).get("id", "") or vehicle.get("vehicle", {}).get("label", "")).strip()
359+
try:
360+
_dest = self.config_entry.data.get("destination", "").split(": ")[-1].split(" (")[0].split(" - ")[0].strip()
361+
except Exception: # the label is cosmetic, it must never break the update
362+
_dest = ""
363+
if _dest:
364+
_label = _line + " → " + _dest + " " + (_veh or _crc)
365+
else:
366+
_label = str(self._route_id) + "(" + str(vehicle["trip"]["direction_id"]) + ")" + _crc + "_" + self._icon.split(':')[1]
367+
geojson_element["properties"]["id"] = _line + "_" + str(vehicle["trip"]["direction_id"]) + "_" + (_veh or _crc)
368+
geojson_element["properties"]["title"] = _label
349369
geojson_element["properties"]["trip_id"] = vehicle["trip"]["trip_id"]
350370
geojson_element["properties"]["route_id"] = str(self._route_id)
351371
geojson_element["properties"]["direction_id"] = vehicle["trip"]["direction_id"]

0 commit comments

Comments
 (0)