feat(incident): render TomTom from/to segments and length in wire output

Line 2 now falls back to from_loc → to_loc when road is absent
(common for TomTom street-level incidents without road_numbers).

Line 3 renders length (meters from TomTom) as human-readable
distance (mi or m) alongside delay and lanes_affected.

Add length field to _parse_tomtom_incident return dict.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt Johnson (via Claude) 2026-06-08 03:41:30 +00:00
commit 198827a1b0

View file

@ -324,6 +324,7 @@ def _parse_tomtom_incident(envelope: dict, now: int) -> Optional[dict]:
"geocoder_city": ge.get("city"), "geocoder_city": ge.get("city"),
"landclass": ge.get("landclass"), "landclass": ge.get("landclass"),
"mile_marker": None, "mile_marker": None,
"length": d.get("length"),
} }
@ -749,8 +750,8 @@ def _render(n: dict) -> str:
"""Multi-line wire string. """Multi-line wire string.
Line 1: {emoji} {display} Near {city}, {state} Line 1: {emoji} {display} Near {city}, {state}
Line 2: {road} {direction_long} | MP {mile_marker} Line 2: {road} {direction_long} | MP {mile_marker} OR {from} {to}
Line 3: {lanes_affected} | {delay} min delay Line 3: {lanes_affected} | {delay} min delay | {length}
Line 3b: {comment} (additional context, if non-duplicate and <=140 chars) Line 3b: {comment} (additional context, if non-duplicate and <=140 chars)
Line 4: Cause: {cause} Line 4: Cause: {cause}
""" """
@ -769,16 +770,22 @@ def _render(n: dict) -> str:
anchor_part = state or "" anchor_part = state or ""
line1 = f"{emoji} {display}{anchor_part}".rstrip("") line1 = f"{emoji} {display}{anchor_part}".rstrip("")
# Line 2: road + direction + mile_marker # Line 2: road + direction + mile_marker OR from/to segment (TomTom case)
road = n.get("road") road = n.get("road")
direction = n.get("direction") direction = n.get("direction")
dir_long = _DIRECTION_LONG.get(direction, direction) if direction else None dir_long = _DIRECTION_LONG.get(direction, direction) if direction else None
mile = n.get("mile_marker") mile = n.get("mile_marker")
from_loc = n.get("from_loc")
to_loc = n.get("to_loc")
parts = [] parts = []
if road and dir_long: if road and dir_long:
parts.append(f"{road} {dir_long}") parts.append(f"{road} {dir_long}")
elif road: elif road:
parts.append(road) parts.append(road)
elif from_loc and to_loc:
parts.append(f"{from_loc}{to_loc}")
elif from_loc:
parts.append(from_loc)
if mile is not None: if mile is not None:
parts.append(f"MP {mile}") parts.append(f"MP {mile}")
line2 = " | ".join(parts) if parts else "" line2 = " | ".join(parts) if parts else ""
@ -791,15 +798,25 @@ def _render(n: dict) -> str:
cause = n.get("cause") cause = n.get("cause")
line4 = f"Cause: {cause}" if cause and cause != "Incident" else "" line4 = f"Cause: {cause}" if cause and cause != "Incident" else ""
# Length (meters from TomTom) formatted as human-readable
length_m = n.get("length")
length_str = ""
if isinstance(length_m, (int, float)) and length_m > 0:
if length_m >= 1609:
length_str = f"{length_m / 1609:.1f} mi"
else:
length_str = f"{int(length_m)}m"
# Optional delay line for tomtom-enriched events # Optional delay line for tomtom-enriched events
delay_minutes = n.get("delay_minutes") delay_minutes = n.get("delay_minutes")
delay_line = f"{delay_minutes} min delay" if delay_minutes else "" delay_line = f"{delay_minutes} min delay" if delay_minutes else ""
# Combine line 3 and delay if both present, else keep them separate # Combine length, delay, and lanes on line 3
if line3 and delay_line: extras = [x for x in (delay_line, length_str) if x]
line3 = f"{line3} | {delay_line}" if line3 and extras:
elif delay_line and not line3: line3 = f"{line3} | " + " | ".join(extras)
line3 = delay_line elif extras:
line3 = " | ".join(extras)
# Line 3b: comment field, if it contains additional context not already in line 3 # Line 3b: comment field, if it contains additional context not already in line 3
comment = n.get("comment") comment = n.get("comment")